ArrayDeque is a resizable-array deque for inserting and removing elements at either end.
Java ArrayDeque for queues and stacks
FIFO work order
import java.util.ArrayDeque;
import java.util.Deque;
public class TaskDequeDemo {
public static void main(String[] args) {
Deque<String> pendingTasks = new ArrayDeque<>();
pendingTasks.addLast("Validate invoice");
pendingTasks.addLast("Send receipt");
System.out.println(pendingTasks.pollFirst());
System.out.println(pendingTasks.pollFirst());
System.out.println(pendingTasks.pollFirst());
}
}The output is Validate invoice, Send receipt, and null. A stack instead pairs push with pop at the same end. Do not mix that convention with addLast and assume the result is FIFO.
Most endpoint operations are amortized O(1). The deque has no List-style get(index) operation. It rejects null elements, which leaves null available as an empty result for poll and peek.
Endpoint absence and memory retention
ArrayDeque rejects null elements, so poll returning null can clearly mean no element was available. It is not a blocking queue and does not wait for a producer to add another element.
A deque can grow to absorb a burst and may retain backing-array capacity after removals. Empty size is not proof that all storage returned to the runtime. Bound queued work according to the application’s memory budget.
Connected lessons
Continue with Java LinkedList: operations, internals and failure cases, Java LinkedList quiz.
An empty queue needs an explicit policy
pollFirst returns null when no element exists, while removeFirst throws. Use poll when empty is an expected state and the caller can choose another task; use a throwing operation when emptiness violates a proven application precondition.
ArrayDeque does not permit null elements, which keeps the null result from poll unambiguous. A LinkedList can contain null, so copying the same interpretation to a LinkedList-backed queue without controlling elements changes the meaning of an empty-looking result.
A stack uses push/pop or consistent first-end operations. A FIFO queue adds at the back and removes from the front. Mixing ends unintentionally changes processing order while every call remains individually valid.
Endpoint speed does not solve shared ownership
Endpoint insertions and removals have amortized constant work; resizing can copy stored references. Searching by value or removing an occurrence can require a full scan. The deque stores O(n) references and implementation capacity, rather than one separately allocated link node for every element.
ArrayDeque is not a concurrent queue. Giving it to two workers without coordination can corrupt the assumptions behind a compound empty-check and remove. A synchronized access policy must cover all participating operations, or use a concurrent collection designed for the required producer/consumer contract.
Clearing pending membership does not cancel a task another worker already removed. Completion, cancellation and queue size are separate facts. See bounded queues for admission and shutdown boundaries.
Common Mistakes
ArrayDeque is not thread-safe and has no fixed capacity limit. Use a bounded or concurrent queue when producers, backpressure, or multiple consumers require those properties.
Next boundary checks
Continue with Java Deque empty operations: choose return values or exceptions.
Continue with range and graph boundaries
Continue with Java next greater element: keep unresolved indices on a stack, Java sliding-window maximum: evict expired indices and weaker tails.
