Java Queue, Deque & Stack: Linear Data Structures for Efficient Operations
Welcome back to the Java Fundamentals series! 👋
Overview of Linear Data Structures
Data Structure | Characteristic | Interface/Implementation |
---|---|---|
Queue | FIFO (First-In-First-Out) | Queue<E> |
Deque | Double-Ended Queue (both ends) | Deque<E> |
Stack | LIFO (Last-In-First-Out) | Stack<E> (legacy), Deque<E> (preferred) |
Queue: First-In-First-Out Operations
Declaration and Initialization
Queue<Integer> q = new LinkedList<>();
Queue<Integer> pq = new PriorityQueue<>();
Essential Queue Operations
Method | Description |
---|---|
add(E) | Adds element, throws exception if capacity exceeded |
offer(E) | Adds element, returns false if capacity exceeded |
poll() | Retrieves and removes head, returns null if empty |
remove() | Retrieves and removes head, throws exception if empty |
peek() | Retrieves but does not remove head, null if empty |
element() | Retrieves but does not remove head, throws exception if empty |
Note: PriorityQueue maintains natural or comparator-defined ordering.
Deque: Double-Ended Queue Operations
Can be used as both Queue and Stack operations from both ends.
Declaration and Initialization
Deque<Integer> dq = new ArrayDeque<>();
Essential Deque Operations
Method | Description |
---|---|
addFirst(E) / offerFirst(E) | Add to head |
addLast(E) / offerLast(E) | Add to tail |
removeFirst() / pollFirst() | Remove head |
removeLast() / pollLast() | Remove tail |
peekFirst() / peekLast() | Retrieve head/tail |
Performance Tip: ArrayDeque is preferred over LinkedList for Deque operations (faster, no capacity restriction).
Stack: Last-In-First-Out Operations
Legacy Stack Class
⚠️ Important: The
Stack
class should generally be avoided for new code. UseDeque
as a stack instead.
Stack<Integer> s = new Stack<>();
Stack Operations
Method | Description |
---|---|
push(E) | Add to top |
pop() | Remove from top |
peek() | View top |
empty() | Check if empty |
Real-World Use Cases
Understanding when to use each data structure is crucial for efficient programming:
Queue Applications
- CPU Scheduling: Process management in operating systems
- Print Spoolers: Managing print jobs in order
- Breadth-First Search (BFS): Graph traversal algorithms
- Buffer for Data Streams: Managing incoming data packets
PriorityQueue Applications
- Dijkstra's Algorithm: Shortest path finding
- Task Prioritization: Managing tasks by priority level
- Huffman Coding: Data compression algorithms
- A Search Algorithm*: Pathfinding with heuristics
Deque Applications
- Palindrome Checking: Comparing characters from both ends
- Sliding Window Maximum: Efficient window-based calculations
- Undo/Redo Operations: Browser history, text editors
- Work-Stealing Algorithms: Multi-threaded task distribution
Stack Applications
- Expression Parsing: Evaluating mathematical expressions
- Backtracking Algorithms: DFS, maze solving, N-Queens
- Function Call Management: Method call stack
- Undo Operations: Single-level undo functionality
Performance Analysis
Time Complexities
Operation | Queue (LinkedList) | Deque (ArrayDeque) | Stack (Deque) |
---|---|---|---|
Add/Offer | O(1) | O(1) | O(1) |
Remove/Poll | O(1) | O(1) | O(1) |
Peek | O(1) | O(1) | O(1) |
Note: PriorityQueue operations are O(log n) for add/remove due to heap maintenance.
Quick Comparison Summary
Structure | Insertion Point | Removal Point |
---|---|---|
Queue | Rear | Front |
Deque | Both | Both |
Stack | Top | Top |
Best Practices and Common Pitfalls
Best Practices
- Prefer ArrayDeque for Deque and Stack operations over LinkedList and Stack
- Use offer/poll/peek variants for safety (no exceptions on capacity/empty)
- Choose the right implementation based on your specific use case
- Program to interfaces (
Queue
,Deque
) rather than concrete classes
Common Pitfalls to Avoid
- Don't mix null values with ArrayDeque — it does not allow nulls
- Avoid using Stack class for new development — use Deque instead
- Be careful with PriorityQueue ordering — ensure elements are Comparable or provide Comparator
- Don't assume insertion order with PriorityQueue — it's a heap, not a sorted list
Conclusion
- Queue: FIFO operations with
LinkedList
orPriorityQueue
implementations - Deque: Flexible double-ended operations with
ArrayDeque
as the preferred choice - Stack: LIFO operations best implemented using
Deque
interface - Performance matters: Choose the right implementation for your specific use case
- Safety first: Use
offer/poll/peek
methods to avoid exceptions
Happy coding! 💻