Criteria | Queue | Stack |
---|---|---|
Data Structure Type | FIFO (First-In-First-Out) | LIFO (Last-In-First-Out) |
Primary Operations | offer (or add), poll (or remove), peek | push, pop, peek |
Example Use Case | Order processing where the first order received is the first to be processed. | Undo functionality in software, where the last action taken is the first to be undone. |
Implementation in Java Collections Framework | Interfaces like Queue, Deque and classes like LinkedList, ArrayDeque, PriorityQueue, etc. | Class Stack. However, it’s more common to use Deque (like ArrayDeque) for stack operations in modern Java. |
Thread Safety | Implementations like ArrayDeque are not thread-safe. For a thread-safe queue, you can use ConcurrentLinkedQueue or use wrappers like Collections.synchronizedQueue(). | Stack class is not thread-safe. For thread safety, you might consider using ConcurrentLinkedDeque or use wrappers like Collections.synchronizedDeque() when using a Deque as a stack. |
Performance | Depends on the implementation. For instance, LinkedList and ArrayDeque offer constant time for insertions and removals. | Stack class provides constant time for push and pop operations, but modern Java prefers using Deque implementations like ArrayDeque for better performance and versatility. |
Memory Footprint | Depends on the implementation. ArrayDeque is usually more memory efficient than LinkedList for queue operations. | Stack uses a vector for storage. Using ArrayDeque for stack operations is typically more memory efficient. |
Example: Difference Between Queue and Stack in Java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class QueueVsStackDemo {
public static void main(String[] args) {
// Using a Queue (FIFO: First In, First Out)
Queue<String> queue = new LinkedList<>();
queue.add("A");
queue.add("B");
queue.add("C");
// Using a Stack (LIFO: Last In, First Out)
Stack<String> stack = new Stack<>();
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println("Queue Front Element: " + queue.peek());
System.out.println("Stack Top Element: " + stack.peek());
System.out.println("Removing from Queue: " + queue.poll());
System.out.println("Removing from Stack: " + stack.pop());
System.out.println("Queue after removing element: " + queue);
System.out.println("Stack after removing element: " + stack);
}
}
Output:
Queue Front Element: A Stack Top Element: C Removing from Queue: A Removing from Stack: C Queue after removing element: [B, C] Stack after removing element: [A, B]
Explanation:
1. Queue: It is a collection designed for holding elements prior to processing. It follows the FIFO (First In, First Out) principle which means the item that has been in the queue the longest is the first one to be removed.
2. Stack: It is a collection designed for LIFO (Last In, First Out) data management. This means the last item added is the first one to be removed.
3. In the provided example:
– For Queue: We added elements "A", "B", and "C". When we checked the front element using peek(), it returned "A" as it was the first to be inserted. Removing an element using poll() also removed "A", following the FIFO principle.
– For Stack: We pushed elements "A", "B", and "C". The peek() method returned "C" as it was the last to be added. When removing an element using pop(), "C" was the one to be removed, adhering to the LIFO principle.
4. When to use:
– Use Queue when you need to manage elements in a FIFO manner, like in task scheduling.
– Use Stack for scenarios that require LIFO behavior, such as certain algorithms and problems like balancing parentheses or backtracking.
The fundamental difference between Queue and Stack lies in how elements are added and removed. While a queue removes the oldest item, a stack removes the newest item.