JVM / Java / Collections / Queues

1. Queue Basics

Queue = Fist In, First Out As analogy, imagine a line at supermarket. First persion in line, first served. New people join at the end. Java provides two versions of the same operations to handle failure differently (add or offer). - if fails, add() throw exception, offer() return false - if empty, remove() throws exception, poll() return null - if empty, element() throws exception, peek() return null Prefer offer(), poll(), peek(). They are safer and more commonly used.
 
import java.util.ArrayDeque;
import java.util.Queue;

public class QueueBasics {
    public static void main(String[] args) {
        
        // Create a Queue
        Queue<String> queue = new ArrayDeque<>();

        // Add elements (People entering line)
        queue.offer("Alice");
        queue.offer("Bob");
        queue.offer("Charlie");

        // View front (Next to be served)
        String first = queue.peek();
        System.out.println("Next customer: " + first);  // Alice

        // Remove element (Serving customer)
        String served = queue.poll();
        System.out.println("Served: " + served);  // Alice
        System.out.println("Queue after serving: " + queue);  // [Bob, Charlie]

        // Add more people
        queue.offer("Diana");
        queue.offer("Eva");
        System.out.println("Updated queue: " + queue);  // [Bob, Charlie, Diana, Eva]

        // Process entire queue
        while (!queue.isEmpty()) {
            System.out.println("Serving: " + queue.poll()); 
                // Bob
                // Charlie ...
        }
    }
}

2. Deque Example

Deque allows insertion and removal from BOTH ends. This makes it more powerful than a Queue. Better performance with ArrayDeque. Use Deque for most cases (best performance).
 
package collections.queues;

import java.util.ArrayDeque;
import java.util.Deque;

public class DequeExample {
    public static void main(String[] args) {
        
        // Create Deque
        Deque<String> deque = new ArrayDeque<>(); // Both ends (not like Queue)

        // Use as queue (FIFO)
        deque.offerLast("Alice");  // same as addLast (but better)
        deque.offerLast("Bob");
        deque.offerLast("Charlie");
        System.out.println("Serve: " + deque.pollFirst()); // remove from front (Alice)

        // Use as stack (LIFO)
        deque.push("X");  // same as addFirst
        deque.push("Y");
        deque.push("Z");
        System.out.println("Pop: " + deque.pop());  // Z

        // Working with both end
        deque.addFirst("Start");
        deque.addLast("End");
        System.out.println(deque);  // [Start, Y, X, Bob, Charlie, End]
        System.out.println("Remove first: " + deque.removeFirst());  // Start
        System.out.println("Remove last: " + deque.removeLast());  // End

        // Peek operations
        System.out.println("Peek first: " + deque.peekFirst());  // Y
        System.out.println("Peek last: " + deque.peekLast());  // Charlie
    }
}