W3docs

Java Deque Interface

Double-ended queue operations in Java with the Deque interface — addFirst, addLast, pollFirst, pollLast.

Java Deque Interface

Deque<E> — pronounced "deck," short for double-ended queue — is Queue<E> with a second end. Where a Queue only lets you remove from the head, a Deque lets you insert, remove, and examine at both the head and the tail. That single extra capability is enough to make Deque the contract behind two completely different abstractions: it's a queue, it's a stack, and the JDK recommends it as the default for both.

Two ends × three operations × two error styles

The interface looks intimidating at first because every operation appears in twelve shapes — head vs tail, insert vs remove vs examine, throws vs returns-special-value. But it's just the Queue 3×2 grid stretched across two ends:

OperationFirst (head) — throwsFirst (head) — special valueLast (tail) — throwsLast (tail) — special value
InsertaddFirst(e)offerFirst(e)addLast(e)offerLast(e)
RemoveremoveFirst()pollFirst()removeLast()pollLast()
ExaminegetFirst()peekFirst()getLast()peekLast()

The "throws" column is the one you call when an empty/full deque at that point would be a bug. The "special value" column is the one you call when emptiness is an expected state and you want to test for it in a loop condition.

The queue mapping

Deque extends Queue, so a Deque is a Queue. The inherited methods are aliases for the head-from-tail variants:

Queue methodDeque equivalent
add(e) / offer(e)addLast(e) / offerLast(e)
remove() / poll()removeFirst() / pollFirst()
element() / peek()getFirst() / peekFirst()

Insert at the tail, remove from the head — that's the FIFO discipline a Queue already gives you, just spelled with the end-explicit names.

The stack mapping

Deque also defines three "stack" methods that all act on the head:

Stack methodDeque equivalent
push(e)addFirst(e)
pop()removeFirst()
peek()peekFirst()

Push on, pop off — LIFO discipline, same head, opposite end of the insert/remove from the queue mapping. This is why the Stack chapter pointed you here: the modern way to write a stack in Java is Deque<E> stack = new ArrayDeque<>(); and call push / pop / peek.

The rule: null is not allowed

Like Queue, the Deque contract reserves null as the "empty" sentinel for pollFirst, pollLast, peekFirst, peekLast. So every general-purpose Deque in the JDK rejects null elements with NullPointerException on insert. The single exception is LinkedList, which permits null for historical reasons — and inherits all the ambiguity that comes with it. Don't do that.

Iteration and reverse iteration

A Deque has two iterators by convention:

  • iterator() walks head to tail — the order you'd pollFirst repeatedly.
  • descendingIterator() walks tail to head — the order you'd pollLast repeatedly.

Both are typically fail-fast: mutating the deque from outside the iterator while iterating throws ConcurrentModificationException. Use Iterator.remove() or removeIf if you need to mutate during a walk.

Picking an implementation

In single-threaded code there are essentially two choices:

  • ArrayDeque — the default. Circular array, O(1) at both ends, no per-element node allocation, cache-friendly. Rejects null. Implements Deque and Queue.
  • LinkedList — doubly-linked nodes. Also implements List, so each element gets a node with prev/next pointers. Slower at both ends than ArrayDeque and uses more memory. Pick it only if you actually need Deque and List semantics on the same object.

For concurrent code (covered later in the concurrency part of the book):

  • ConcurrentLinkedDeque — lock-free, unbounded.
  • LinkedBlockingDeque — optionally bounded, blocking — the version you'd use to build a work-stealing queue or a producer/consumer with back-pressure at either end.

A worked example: queue, stack, and palindrome check in one deque

The program below uses one ArrayDeque as a FIFO queue, another as a LIFO stack, and a third to check whether a sentence is a palindrome by feeding both ends and comparing. The point is that the same interface, even the same class, plays all three roles.

java— editable, runs on the server

What this run shows:

  • The same class fills both queue and stack roles without renaming a single method beyond which end you address.
  • The "returns special value" methods quietly produce null for empty; the "throws" methods raise NoSuchElementException. Choose by whether emptiness is expected or a bug.
  • The palindrome check uses both ends in the same looppollFirst and pollLast together. That's the access pattern only a Deque gives you cheaply.

What's next

The Deque chapter closes the queue-side of the framework. The other big abstraction in Collection is the one that rejects duplicates: a Set is a Collection with the uniqueness contract baked in. We pick that up next.

Practice

Practice

You want a LIFO stack in modern Java code. Which line matches the JDK recommendation?