Stacks and Queues in Java

Welcome to an exciting exploration of two fundamental data structures in Java: Stacks and Queues! These data structures organize and manage data effectively. Specifically, stacks are comparable to a pile of plates, while queues are akin to standing in line. Let's dive in!

Stacks: Last In, First Out (LIFO)

A stack follows the "Last In, First Out" or LIFO principle. Imagine a stack of plates where the last plate added is the first one to be removed. In Java, we can use ArrayDeque<E> or LinkedList<E> to implement a stack, with push for inserting (pushing) and pop for removing (popping, returning the element that is removed).

  • Push (Insertion): Adds an element to the top of the stack. This makes the newly added element the last-in, which is the first to be removed when needed.
  • Pop (Removal): Removes and returns the element at the top of the stack, following the Last In, First Out (LIFO) principle.

Let's explore this with an example of a stack of plates.

The last plate added was removed first, demonstrating the LIFO property of a stack.

Queues: First In, First Out (FIFO)

A queue operates on the "First In, First Out" or FIFO principle, similar to waiting in line. In Java, we can implement a queue using the Queue<E> interface with a LinkedList or ArrayDeque, where add (enqueue) inserts at the end and remove or poll (dequeue) removes from the front.

  • Add (Enqueue): Adds an element to the end of the queue, following the First In, First Out (FIFO) order.
  • Poll (Dequeue): Removes and returns the element at the front of the queue. This is the oldest element, maintaining the FIFO order.

Let's examine this with a queue of people.

Here, Person 1, the first to join the queue, left before Person 2, demonstrating the FIFO property of a queue.

Mastering Stack and Queue Operations with a Class

Stacks efficiently handle ordered data, much like a web browser's history. Queues are optimal when the order of arrival is essential, such as in a store queue.

Let's illustrate using a text editor that features an Undo mechanism (a Stack) and a Print Queue.

Undo Mechanism (Stack):

  • The makeChange(String action) method pushes each action onto the stack, simulating the latest edit. When an undo is performed using undoChange(), it removes this most recent change from the stack, just as pressing "Undo" would revert the last action. The stack's LIFO property ensures that the latest change is always the first undone.

Print Queue (Queue):

  • The addToPrint(String doc) method enqueues documents for printing, adding each one to the end of the queue. When printDoc() is called, it dequeues the document at the front, following the order of addition. This FIFO process simulates a print queue, where the earliest document in line is printed first.

This code reintroduces the concepts of a Stack (Undo feature) and Queue (Print queue) in practical scenarios.

Why ArrayDeque for Stack and LinkedList for Queue?

When choosing the right data structure for stacks and queues in Java, ArrayDeque and LinkedList offer distinct advantages tailored to their respective operations.

For implementing a stack, ArrayDeque is often the preferred choice. This is because:

  • ArrayDeque is optimized for stack operations: It allows fast, constant-time push and pop operations at the start of the deque. Additionally, ArrayDeque is more efficient than Java's legacy Stack class, which is synchronized and incurs unnecessary overhead when used in single-threaded contexts.
  • Memory Efficiency: ArrayDeque uses a contiguous array, which avoids the structural overhead associated with LinkedList, and dynamically grows as needed, optimizing memory usage.

When implementing a queue, LinkedList is particularly well-suited because:

  • LinkedList provides efficient insertion and removal: It efficiently handles operations at both ends, making it ideal for queues where elements are added at the end and removed from the front. This allows LinkedList to manage elements without the need for shifting, which can be a hindrance in array-based structures.
  • Flexibility: LinkedList implements the Queue interface, providing versatility as a queue structure with minimal setup and allowing developers to leverage its native methods seamlessly.
Lesson Summary

Great work! You have explored the mechanics of Stacks and Queues, both integral data structures in Java. Remember to practice what you've learned. Happy coding!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal