[{"data":1,"prerenderedAt":139},["ShallowReactive",2],{"qa-\u002Fjava\u002Fcollections\u002Fqueue-deque":3},{"page":4,"siblings":119,"blog":136},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"questionsCount":109,"related":110,"seo":111,"seoDescription":112,"stem":113,"subtopic":114,"topic":115,"topicSlug":116,"updated":117,"__hash__":118},"qa\u002Fjava\u002Fcollections\u002Fqueue-deque.md","Queue Deque",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Java","java",{},true,4,"\u002Fjava\u002Fcollections\u002Fqueue-deque",[23,28,32,36,40,44,48,53,57,61,65,69,73,77,81,85,89,93,97,101,105],{"id":24,"difficulty":25,"q":26,"a":27},"queue-interface","easy","What is the Queue interface in Java?","`Queue\u003CE>` is a `Collection` that models a **FIFO** (first-in, first-out) order:\nelements are added at the **tail** and removed from the **head**. It extends\n`Collection` and is implemented by `LinkedList`, `ArrayDeque`,\n`PriorityQueue`, and the concurrent\u002Fblocking queues.\n\n```java\nQueue\u003CString> q = new LinkedList\u003C>();\nq.offer(\"a\");           \u002F\u002F enqueue at tail\nq.offer(\"b\");\nString head = q.poll(); \u002F\u002F dequeue from head -> \"a\"\nString next = q.peek(); \u002F\u002F look without removing -> \"b\"\n```\n\nNote that not every `Queue` is FIFO: `PriorityQueue` orders by priority and a\n`Deque` used as a stack is LIFO. The interface only guarantees the head is the\nelement returned by `peek`\u002F`poll` — the *ordering policy* is the\nimplementation's job.\n",{"id":29,"difficulty":14,"q":30,"a":31},"queue-method-families","What are the two method families on Queue (throwing vs returning)?","Every core `Queue` operation comes in **two flavours**: one that **throws** an\nexception on failure and one that returns a **special value** (`false` or\n`null`). Use the throwing form when failure is a bug; use the returning form\nwhen emptiness\u002Ffullness is expected control flow.\n\n| Operation | Throws on failure | Returns special value |\n| --------- | ----------------- | --------------------- |\n| Insert | `add(e)` (throws `IllegalStateException` if full) | `offer(e)` (returns `false`) |\n| Remove head | `remove()` (throws `NoSuchElementException` if empty) | `poll()` (returns `null`) |\n| Examine head | `element()` (throws `NoSuchElementException` if empty) | `peek()` (returns `null`) |\n\n```java\nQueue\u003CInteger> q = new ArrayDeque\u003C>();\nq.poll();      \u002F\u002F null  — empty, no exception\nq.remove();    \u002F\u002F NoSuchElementException\n```\n\nThe returning forms (`offer`\u002F`poll`\u002F`peek`) are the safer default for\nbounded\u002Fconcurrent queues where failure is normal.\n",{"id":33,"difficulty":14,"q":34,"a":35},"deque-interface","What is a Deque and how does it differ from a Queue?","`Deque\u003CE>` (\"double-ended queue\", pronounced \"deck\") lets you insert, remove,\nand examine at **both ends**. It extends `Queue`, so it can act as a plain FIFO\nqueue, but it adds a full set of `*First`\u002F`*Last` methods.\n\n```java\nDeque\u003CInteger> d = new ArrayDeque\u003C>();\nd.addFirst(1);   \u002F\u002F [1]\nd.addLast(2);    \u002F\u002F [1, 2]\nd.peekFirst();   \u002F\u002F 1\nd.peekLast();    \u002F\u002F 2\nd.pollFirst();   \u002F\u002F removes 1 -> [2]\n```\n\nBecause both ends are O(1), a `Deque` is the one structure that can serve as\n**either a FIFO queue or a LIFO stack** — which is exactly why modern code uses\nit in place of the legacy `Stack` class.\n",{"id":37,"difficulty":14,"q":38,"a":39},"deque-method-table","What are the end-specific methods on Deque?","Each end has the same throwing-vs-returning split as `Queue`, doubled for first\nand last:\n\n| | First (head) throws | First returns | Last (tail) throws | Last returns |\n| --- | --- | --- | --- | --- |\n| Insert | `addFirst(e)` | `offerFirst(e)` | `addLast(e)` | `offerLast(e)` |\n| Remove | `removeFirst()` | `pollFirst()` | `removeLast()` | `pollLast()` |\n| Examine | `getFirst()` | `peekFirst()` | `getLast()` | `peekLast()` |\n\n```java\nDeque\u003CString> d = new ArrayDeque\u003C>();\nd.offerFirst(\"x\");   \u002F\u002F returns boolean, no throw\nd.peekLast();        \u002F\u002F null if empty, no throw\nd.getFirst();        \u002F\u002F NoSuchElementException if empty\n```\n\nThe throwing forms (`getFirst`, `removeLast`) fail loudly on an empty deque;\nthe returning forms (`peekFirst`, `pollLast`) give `null`. The inherited\n`Queue` methods map to the **first** end for removal and the **last** for\ninsertion.\n",{"id":41,"difficulty":14,"q":42,"a":43},"deque-as-stack","How do you use a Deque as a stack?","`Deque` provides `push`, `pop`, and `peek`, which operate on the **head** as a\n**LIFO** stack: `push` is `addFirst`, `pop` is `removeFirst`, `peek` is\n`peekFirst`.\n\n```java\nDeque\u003CInteger> stack = new ArrayDeque\u003C>();\nstack.push(1);   \u002F\u002F [1]\nstack.push(2);   \u002F\u002F [2, 1]  (head is the top)\nstack.peek();    \u002F\u002F 2\nstack.pop();     \u002F\u002F 2  -> [1]\n```\n\nBoth ends are O(1), so this is a fast, clean stack. Note `pop`\u002F`peek` here\n**throw** `NoSuchElementException` on an empty deque (unlike `poll`\u002F`peekFirst`,\nwhich return `null`).\n",{"id":45,"difficulty":14,"q":46,"a":47},"arraydeque-vs-stack","Why is ArrayDeque preferred over the legacy Stack class?","`java.util.Stack` extends `Vector`, which makes it **synchronized** on every\noperation (slow, and pointless for single-threaded use) and, worse, it exposes\n`Vector`'s index methods so you can `get(i)`\u002F`insertElementAt` into the middle —\nbreaking the stack abstraction. It also iterates **bottom-to-top**, the opposite\nof pop order.\n\n```java\n\u002F\u002F legacy — avoid\nStack\u003CInteger> old = new Stack\u003C>();\n\n\u002F\u002F modern stack — fast, clean LIFO\nDeque\u003CInteger> stack = new ArrayDeque\u003C>();\nstack.push(1);\nstack.pop();\n```\n\nThe Javadoc itself recommends `ArrayDeque` for stack use. It's unsynchronized\n(faster), has a tight contract (no random access), and iterates in the correct\norder.\n",{"id":49,"difficulty":50,"q":51,"a":52},"arraydeque-vs-linkedlist","hard","What is the difference between ArrayDeque and LinkedList as a Deque?","Both implement `Deque`, but the data structure underneath differs:\n\n| | `ArrayDeque` | `LinkedList` |\n| --- | --- | --- |\n| Backing store | resizable **circular array** | **doubly-linked** nodes |\n| Memory | one compact array | a node object + 2 pointers per element |\n| Cache locality | excellent (contiguous) | poor (scattered nodes) |\n| Allows `null` | **no** | yes |\n| Also implements | `Queue`, `Deque` | `List`, `Queue`, `Deque` |\n\n```java\nDeque\u003CInteger> fast = new ArrayDeque\u003C>();   \u002F\u002F prefer this\nDeque\u003CInteger> list = new LinkedList\u003C>();    \u002F\u002F only if you need List ops\n```\n\nFor pure queue\u002Fstack\u002Fdeque use, **`ArrayDeque` is faster** thanks to contiguous\nmemory and no per-element node allocation. Pick `LinkedList` only when you also\nneed `List` behavior (indexing, `ListIterator`) or must store `null`.\n",{"id":54,"difficulty":14,"q":55,"a":56},"arraydeque-no-nulls","Why does ArrayDeque not allow null elements?","`ArrayDeque` (and most queues) **reject `null`** because `null` is the **sentinel\nvalue** returned by `poll`\u002F`peek` to mean \"the queue is empty.\" If a real `null`\nelement were allowed, you couldn't tell an empty queue from a queue whose head is\n`null`.\n\n```java\nDeque\u003CString> d = new ArrayDeque\u003C>();\nd.offer(null);   \u002F\u002F NullPointerException\nd.poll();        \u002F\u002F null only ever means \"empty\"\n```\n\nSo the no-null rule keeps the returning-value method family unambiguous.\n`LinkedList` predates this design and permits `null`, which is one more reason to\navoid it as a queue.\n",{"id":58,"difficulty":14,"q":59,"a":60},"priorityqueue","What is a PriorityQueue and how is it ordered?","`PriorityQueue` is a `Queue` whose **head is always the smallest element** by\nthe ordering — not FIFO. It's backed by a **binary heap**, so `peek`\u002F`poll`\nreturn the minimum and `offer`\u002F`poll` are O(log n).\n\n```java\nPriorityQueue\u003CInteger> pq = new PriorityQueue\u003C>();\npq.offer(5);\npq.offer(1);\npq.offer(3);\npq.poll();   \u002F\u002F 1  — smallest first\npq.poll();   \u002F\u002F 3\n```\n\nOrdering comes from the elements' **`Comparable`** (natural order) or a\n**`Comparator`** passed to the constructor. It allows duplicates but, like other\nqueues, **not `null`**, and elements must be mutually comparable or you get a\n`ClassCastException`.\n",{"id":62,"difficulty":14,"q":63,"a":64},"priorityqueue-comparator","How do you build a max-heap or custom-ordered PriorityQueue?","By default a `PriorityQueue` is a **min-heap** (natural order). Pass a\n`Comparator` to change the policy — `reverseOrder()` makes a max-heap, and a\nkey extractor orders by a field.\n\n```java\n\u002F\u002F max-heap: largest first\nPriorityQueue\u003CInteger> max = new PriorityQueue\u003C>(Comparator.reverseOrder());\nmax.offer(1); max.offer(9); max.offer(5);\nmax.poll();   \u002F\u002F 9\n\n\u002F\u002F order tasks by priority field\nPriorityQueue\u003CTask> tasks =\n    new PriorityQueue\u003C>(Comparator.comparingInt(Task::priority));\n```\n\nThe comparator is fixed at construction. For objects, supplying a `Comparator`\n(or implementing `Comparable`) is **mandatory** — without an ordering the heap\ncan't decide the head and throws `ClassCastException` on the first `offer`.\n",{"id":66,"difficulty":50,"q":67,"a":68},"priorityqueue-iteration","Does iterating a PriorityQueue return elements in sorted order?","**No.** A `PriorityQueue`'s iterator (and `toString`) traverses the **internal\nheap array**, which is only *partially* ordered — the heap invariant guarantees\na parent precedes its children, not a fully sorted sequence. Only **`poll`**\nreturns elements in priority order.\n\n```java\nPriorityQueue\u003CInteger> pq = new PriorityQueue\u003C>(List.of(5, 1, 3, 2, 4));\nSystem.out.println(pq);            \u002F\u002F e.g. [1, 2, 3, 5, 4] — NOT sorted\n\nwhile (!pq.isEmpty())\n    System.out.print(pq.poll());   \u002F\u002F 12345 — sorted, by draining\n```\n\nTo get a sorted view you must repeatedly `poll` (which empties the queue) or\ncopy into a list and `sort` it. This \"the queue prints unsorted\" surprise is a\nclassic interview trap.\n",{"id":70,"difficulty":14,"q":71,"a":72},"priorityqueue-complexity","What are the time complexities of PriorityQueue operations?","The binary heap gives:\n\n| Operation | Complexity |\n| --------- | ---------- |\n| `offer` \u002F `add` (insert) | O(log n) — sift up |\n| `poll` \u002F `remove()` (poll head) | O(log n) — sift down |\n| `peek` \u002F `element` (head) | O(1) |\n| `remove(Object)` \u002F `contains` | O(n) — linear scan |\n\n```java\nPriorityQueue\u003CInteger> pq = new PriorityQueue\u003C>();\npq.offer(7);     \u002F\u002F O(log n)\npq.peek();       \u002F\u002F O(1)\npq.remove(7);    \u002F\u002F O(n) — must search first\n```\n\nBuilding a heap from a known collection (the constructor that takes one) is\nO(n), better than n inserts. The O(n) `contains`\u002Farbitrary-`remove` is the cost\nto remember: heaps are great at \"give me the min,\" weak at \"find this element.\"\n",{"id":74,"difficulty":14,"q":75,"a":76},"bounded-vs-unbounded","What is the difference between a bounded and an unbounded queue?","An **unbounded** queue grows as needed (limited only by memory) — `LinkedList`,\n`ArrayDeque`, `PriorityQueue`, `ConcurrentLinkedQueue`,\n`LinkedBlockingQueue` (default). A **bounded** queue has a **fixed maximum\ncapacity** set at construction — `ArrayBlockingQueue`, or `LinkedBlockingQueue`\ngiven a capacity.\n\n```java\nQueue\u003CInteger> unbounded = new ArrayDeque\u003C>();          \u002F\u002F grows freely\nBlockingQueue\u003CInteger> bounded = new ArrayBlockingQueue\u003C>(2); \u002F\u002F cap 2\nbounded.offer(1); bounded.offer(2);\nbounded.offer(3);   \u002F\u002F false — full, rejected (offer form)\n```\n\nBounds matter for **back-pressure**: a bounded queue between a producer and\nconsumer prevents a fast producer from exhausting memory. On a full bounded\nqueue, `add` throws, `offer` returns `false`, and `put` (blocking) waits.\n",{"id":78,"difficulty":14,"q":79,"a":80},"blockingqueue","What is a BlockingQueue and what does it add?","`BlockingQueue\u003CE>` (in `java.util.concurrent`) is a thread-safe queue that adds\noperations which **block** instead of failing: `put(e)` waits while the queue is\nfull, and `take()` waits while it's empty. This is the foundation of the\n**producer-consumer** pattern.\n\n```java\nBlockingQueue\u003CTask> q = new LinkedBlockingQueue\u003C>();\n\n\u002F\u002F producer thread\nq.put(task);     \u002F\u002F blocks if full\n\n\u002F\u002F consumer thread\nTask t = q.take(); \u002F\u002F blocks until an element is available\n```\n\nIt also offers timed `offer(e, timeout, unit)` \u002F `poll(timeout, unit)`. Because\nblocking handles the waiting and the queue handles the locking, you rarely need\nmanual `wait`\u002F`notify` for hand-off between threads.\n",{"id":82,"difficulty":14,"q":83,"a":84},"blockingqueue-impls","What are the main BlockingQueue implementations?","The commonly used ones:\n\n| Implementation | Notes |\n| -------------- | ----- |\n| `ArrayBlockingQueue` | **bounded**, array-backed, single lock, optional fairness |\n| `LinkedBlockingQueue` | optionally bounded, linked nodes, **separate** put\u002Ftake locks (higher throughput) |\n| `PriorityBlockingQueue` | unbounded, priority-ordered, `take` blocks when empty |\n| `SynchronousQueue` | **zero capacity** — each `put` waits for a matching `take` |\n| `DelayQueue` | elements become available only after a delay expires |\n\n```java\nBlockingQueue\u003CRunnable> work = new LinkedBlockingQueue\u003C>();\n\u002F\u002F exactly what a ThreadPoolExecutor uses to hold queued tasks\n```\n\n`ArrayBlockingQueue` and `LinkedBlockingQueue` are the workhorses for bounded\nback-pressure; `SynchronousQueue` is a direct hand-off used by cached thread\npools.\n",{"id":86,"difficulty":50,"q":87,"a":88},"producer-consumer","How does a BlockingQueue implement the producer-consumer pattern?","Producers `put` work into a shared `BlockingQueue`; consumers `take` from it.\nThe queue handles **all synchronization and waiting**, so neither side touches\nlocks directly — producers block when it's full, consumers block when it's\nempty, decoupling their speeds.\n\n```java\nBlockingQueue\u003CInteger> q = new ArrayBlockingQueue\u003C>(10);\n\nRunnable producer = () -> { while (true) q.put(produce()); };\nRunnable consumer = () -> { while (true) consume(q.take()); };\n```\n\nA bounded queue gives **back-pressure**: if consumers fall behind, the queue\nfills and producers naturally slow down rather than exhausting memory. A common\nshutdown trick is a \"poison pill\" — a sentinel element that tells a consumer to\nstop.\n",{"id":90,"difficulty":14,"q":91,"a":92},"concurrentlinkedqueue","What is ConcurrentLinkedQueue and when would you use it?","`ConcurrentLinkedQueue` is an **unbounded, thread-safe, non-blocking** FIFO\nqueue. It uses **lock-free** CAS (compare-and-swap) algorithms instead of locks,\nso it scales well under high contention — but it **never blocks**: `poll`\nreturns `null` immediately when empty rather than waiting.\n\n```java\nQueue\u003CEvent> q = new ConcurrentLinkedQueue\u003C>();\nq.offer(event);          \u002F\u002F always succeeds (unbounded)\nEvent e = q.poll();      \u002F\u002F null if empty — no waiting\n```\n\nUse it when many threads enqueue\u002Fdequeue and you **don't** need blocking\nhand-off or capacity bounds. If consumers must *wait* for work, use a\n`BlockingQueue` instead. Note `size()` is O(n) and only approximate under\nconcurrency.\n",{"id":94,"difficulty":50,"q":95,"a":96},"blocking-vs-concurrent","When do you choose a BlockingQueue over a ConcurrentLinkedQueue?","Both are thread-safe FIFO queues; the deciding factor is whether consumers need\nto **wait** for elements.\n\n| | `BlockingQueue` (e.g. `LinkedBlockingQueue`) | `ConcurrentLinkedQueue` |\n| --- | --- | --- |\n| Blocks when empty\u002Ffull | yes (`take`\u002F`put`) | no (`poll` returns `null`) |\n| Capacity bound | available (back-pressure) | always unbounded |\n| Mechanism | locks + condition waits | lock-free CAS |\n| Use case | producer-consumer hand-off | high-throughput non-blocking buffer |\n\n```java\n\u002F\u002F consumer must wait for work -> BlockingQueue\nTask t = blockingQueue.take();\n\n\u002F\u002F poll-and-move-on, never wait -> ConcurrentLinkedQueue\nTask t2 = concurrentQueue.poll();\n```\n\nChoose `BlockingQueue` for classic producer-consumer with back-pressure, and\n`ConcurrentLinkedQueue` when threads should drain available work without ever\nblocking.\n",{"id":98,"difficulty":14,"q":99,"a":100},"why-no-nulls","Why do most Queue implementations forbid null elements?","Because `null` is **overloaded as the \"queue is empty\" signal**: `poll()` and\n`peek()` return `null` when there's nothing to return. Allowing a real `null`\nelement would make that signal ambiguous — you couldn't distinguish \"empty\" from\n\"the head happens to be null.\"\n\n```java\nQueue\u003CString> q = new ArrayDeque\u003C>();\nq.offer(null);   \u002F\u002F NullPointerException\n\u002F\u002F if null were allowed, q.poll() == null would be ambiguous\n```\n\n`ArrayDeque`, `PriorityQueue`, `ConcurrentLinkedQueue`, and the blocking queues\nall reject `null`. The lone exception is `LinkedList` (a pre-`Queue` class),\nwhich is one more reason not to use it as a queue.\n",{"id":102,"difficulty":14,"q":103,"a":104},"deque-traversal-direction","How can you iterate a Deque in both directions?","A normal iterator (or for-each) goes **head to tail**. `Deque` adds\n**`descendingIterator()`**, which walks **tail to head** — handy when a deque is\nused as a stack and you want top-to-bottom order, or to reverse without copying.\n\n```java\nDeque\u003CInteger> d = new ArrayDeque\u003C>(List.of(1, 2, 3));\n\nfor (int x : d) System.out.print(x);          \u002F\u002F 123 (head -> tail)\n\nvar it = d.descendingIterator();\nwhile (it.hasNext()) System.out.print(it.next()); \u002F\u002F 321 (tail -> head)\n```\n\nThere's no random access on a `Deque` (no `get(i)`), so these two iterators are\nhow you traverse it. Structurally modifying the deque during iteration throws\n`ConcurrentModificationException`.\n",{"id":106,"difficulty":25,"q":107,"a":108},"remove-vs-poll-empty","What is returned when you poll or peek an empty queue versus remove or element?","It depends on which method family you call. The **returning** family yields\n`null`; the **throwing** family raises `NoSuchElementException`.\n\n```java\nQueue\u003CInteger> q = new ArrayDeque\u003C>();   \u002F\u002F empty\n\nq.poll();      \u002F\u002F null   (returning form)\nq.peek();      \u002F\u002F null   (returning form)\nq.remove();    \u002F\u002F NoSuchElementException (throwing form)\nq.element();   \u002F\u002F NoSuchElementException (throwing form)\n```\n\nSo check with `isEmpty()` or use `poll`\u002F`peek` when emptiness is expected, and\nreserve `remove`\u002F`element` for cases where an empty queue means a programming\nerror you want surfaced loudly.\n",21,null,{"description":11},"Java Queue and Deque interview questions — the Queue and Deque interfaces, ArrayDeque vs LinkedList, PriorityQueue, the two method families (throwing vs returning), and blocking queues.","java\u002Fcollections\u002Fqueue-deque","Queue & Deque","Collections","collections","2026-06-20","P1bd1YfI2HhW1lc6rU5Pvf_lVObUEOkWY4Emz71jbxA",[120,124,127,131,132],{"subtopic":121,"path":122,"order":123},"Lists, Maps & Sets","\u002Fjava\u002Fcollections\u002Flist-map-set",1,{"subtopic":125,"path":126,"order":12},"HashMap Internals","\u002Fjava\u002Fcollections\u002Fhashmap-internals",{"subtopic":128,"path":129,"order":130},"Set Implementations","\u002Fjava\u002Fcollections\u002Fset-implementations",3,{"subtopic":114,"path":21,"order":20},{"subtopic":133,"path":134,"order":135},"Comparable & Comparator","\u002Fjava\u002Fcollections\u002Fcomparable-comparator",5,{"path":137,"title":138},"\u002Fblog\u002Fjava-queue-deque-arraydeque-priorityqueue","Java Queue & Deque — ArrayDeque, PriorityQueue & Producer-Consumer",1782244116240]