Queue, Deque & ArrayDeque in Java
FIFO/LIFO, offer/poll/peek vs add/remove/element.
The waiting line
A **Queue processes elements in order, usually first-in, first-out (FIFO). offer adds to the tail, poll takes the head, peek** looks at the head without removing it.
Queue<String> q = new ArrayDeque<>();
q.offer("a"); // [a]
q.offer("b"); // [a, b]
q.peek(); // "a" (still there)
q.poll(); // "a" → [b]Two flavours of every operation
Each operation comes in two flavours. One throws when it can't do its job; the other returns a special value like null. On an empty queue, poll() gives null but remove() throws **NoSuchElementException**.
// throws returns special value
add(x) offer(x) // insert
remove() poll() // take head
element() peek() // read headYour turn
What does this print?
Queue<String> q = new ArrayDeque<>();
q.offer("x");
q.offer("y");
q.offer("z");
String out = q.poll() + q.peek() + q.size();
System.out.println(out);xy2xx3xy3
Show the answer
FIFO: poll() removes x, peek() reads the new head y without removing it, leaving 2 elements.
Deque = queue + stack
A **Deque (double-ended queue) works at both ends. Used as a stack**, push, pop and peek all work at the front. pop() on an empty deque throws NoSuchElementException. When printed, a deque shows front to back.
Deque<String> d = new ArrayDeque<>();
d.offerLast("a"); // queue style: [a]
d.push("z"); // stack style: [z, a]
d.pop(); // "z" (the front)Stack it up
What does this print?
Deque<String> stack = new ArrayDeque<>();
stack.push("a");
stack.push("b");
stack.push("c");
System.out.println(stack.pop() + " " + stack);a [b, c]c [b, a]c [a, b]
Show the answer
Each push goes on the front: [c, b, a]. pop() takes the front, c, and the deque prints front to back: [b, a].
No nulls allowed
**ArrayDeque rejects null** with NullPointerException. It's on purpose: poll() and peek() use null to mean "empty", so a stored null would be ambiguous.
Deque<String> d = new ArrayDeque<>();
d.poll(); // null: empty, fine
d.offer(null); // NullPointerExceptionQueues everywhere
Breadth-first search, job queues, undo stacks, browser history, parsing brackets: all ArrayDeque territory. Its Javadoc notes it is likely faster than Stack used as a stack and faster than LinkedList used as a queue, which is why it's the default choice.
Key takeaways
- Queue: offer (add to tail), poll (take head), peek (look at head)
- Throwing versions: add, remove, element
- Stack via Deque: push, pop, peek — all at the front
- ArrayDeque doesn't allow null elements
💡 A Deque is a train you can board or leave from either end.
ArrayDeque is a circular buffer: head and tail indexes wrap around the end of its internal array, so adding at the front never has to shift anything.
Practice questions
What does this print?
Queue<String> q = new ArrayDeque<>();
q.offer("a");
q.offer("b");
q.offer("c");
System.out.println(q.poll() + q.peek() + q.size());- ab2
- aa3
- ca2
- ab3
Check your answer
ab2. FIFO: poll removes "a", peek reads the new head "b" without removing it, leaving 2 elements.
What does this print?
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop() + " " + stack);- 1 [2, 3]
- 3 [1, 2]
- 3 [2, 1]
- 1 [3, 2]
Check your answer
3 [2, 1]. push adds at the front, so the deque is [3, 2, 1]. pop removes the front (3). ArrayDeque prints from front to back: [2, 1].