<code>ArrayDeque</code> in Java β€” The Fast Queue and Stack

ArrayDeque is a double-ended queue (deque) backed by a resizable circular array. It's O(1) for add/remove at both ends, faster than LinkedList (cache locality) and faster than the legacy Stack (no synchronisation). Use it whenever you want a queue, stack, or both.

As a FIFO queue

var queue = new ArrayDeque<String>();
queue.offer("a");                 // add at tail
queue.offer("b");
queue.poll();                     // "a" β€” remove head
queue.peek();                     // "b" β€” look at head without removing

As a LIFO stack

var stack = new ArrayDeque<Integer>();
stack.push(1);                    // add at head
stack.push(2);
stack.push(3);
stack.pop();                      // 3
stack.peek();                     // 2

Never use java.util.Stack. It extends Vector, is synchronised (slow), and the API is idiosyncratic. ArrayDeque replaces it completely.

Full deque API

var d = new ArrayDeque<Integer>();
d.addFirst(1);   d.addLast(2);
d.peekFirst();   d.peekLast();
d.pollFirst();   d.pollLast();
d.size();        d.isEmpty();

for (int x : d) ...               // iterates from head to tail

Why not LinkedList?

  • Cache-friendly: contiguous memory vs pointer chase.
  • ~3Γ— lower memory overhead per element.
  • Wins on both push-front and push-back microbenchmarks on the JVM.

Thread safety

ArrayDeque is not thread-safe. For cross-thread queues use ConcurrentLinkedQueue, LinkedBlockingQueue or ArrayBlockingQueue from java.util.concurrent.

Common mistakes

  • Using Stack β€” legacy. Use ArrayDeque.
  • Using LinkedList as a queue β€” ArrayDeque is strictly faster.
  • null elements β€” ArrayDeque forbids null. poll() returns null to mean "empty", so inserting null would create an ambiguity.

Related

Pillar: Java collections. Siblings: ArrayList, LinkedList.