[{"data":1,"prerenderedAt":109},["ShallowReactive",2],{"qa-\u002Fjava\u002Fmodern-java\u002Fsequenced-collections":3},{"page":4,"siblings":77,"blog":106},{"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":68,"related":69,"seo":70,"seoDescription":71,"stem":72,"subtopic":6,"topic":73,"topicSlug":74,"updated":75,"__hash__":76},"qa\u002Fjava\u002Fmodern-java\u002Fsequenced-collections.md","Sequenced Collections",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"easy","md","Java","java",{},true,8,"\u002Fjava\u002Fmodern-java\u002Fsequenced-collections",[23,27,31,35,40,44,48,52,56,60,64],{"id":24,"difficulty":14,"q":25,"a":26},"what-are-sequenced-collections","What are sequenced collections and why were they added in Java 21?","**Sequenced collections** (Java 21, JEP 431) introduce three new\ninterfaces — `SequencedCollection`, `SequencedSet`, and `SequencedMap` —\nthat give a **uniform API for accessing the first and last elements** and\nfor **iterating in reverse order** across all ordered collection types.\n\nBefore Java 21 each collection had its own non-uniform way to get the\nfirst or last element:\n\n```java\nList\u003CString> list = List.of(\"a\", \"b\", \"c\");\nlist.get(0);                           \u002F\u002F first element\nlist.get(list.size() - 1);             \u002F\u002F last element — verbose\n\nDeque\u003CString> deque = new ArrayDeque\u003C>(list);\ndeque.peekFirst();                     \u002F\u002F first\ndeque.peekLast();                      \u002F\u002F last\n\nSortedSet\u003CString> sorted = new TreeSet\u003C>(list);\nsorted.first();                        \u002F\u002F first\nsorted.last();                         \u002F\u002F last\n```\n\n`SequencedCollection` unifies these with `getFirst()` \u002F `getLast()`.\n\n**Rule of thumb:** if you need the first or last element, check whether\nthe collection is a `SequencedCollection` and use the new API.\n",{"id":28,"difficulty":14,"q":29,"a":30},"sequenced-collection-interface","What methods does SequencedCollection add?","`SequencedCollection\u003CE>` extends `Collection\u003CE>` and adds:\n\n| Method | Description |\n|---|---|\n| `getFirst()` | Returns the first element; throws `NoSuchElementException` if empty |\n| `getLast()` | Returns the last element; throws `NoSuchElementException` if empty |\n| `addFirst(E)` | Inserts at the beginning (optional — throws `UnsupportedOperationException` for fixed-size) |\n| `addLast(E)` | Inserts at the end (optional) |\n| `removeFirst()` | Removes and returns the first element (optional) |\n| `removeLast()` | Removes and returns the last element (optional) |\n| `reversed()` | Returns a reversed view of the collection |\n\n```java\nList\u003CString> list = new ArrayList\u003C>(List.of(\"a\", \"b\", \"c\"));\n\nSystem.out.println(list.getFirst()); \u002F\u002F \"a\"\nSystem.out.println(list.getLast());  \u002F\u002F \"c\"\n\nlist.addFirst(\"z\");                  \u002F\u002F [\"z\", \"a\", \"b\", \"c\"]\nlist.addLast(\"x\");                   \u002F\u002F [\"z\", \"a\", \"b\", \"c\", \"x\"]\n\nlist.removeFirst();                  \u002F\u002F \"z\" removed\nlist.removeLast();                   \u002F\u002F \"x\" removed\n```\n\n**Rule of thumb:** `getFirst()`\u002F`getLast()` replace `get(0)` and\n`get(list.size()-1)` — use them for cleaner, more readable code.\n",{"id":32,"difficulty":14,"q":33,"a":34},"sequenced-set-interface","What is SequencedSet and which classes implement it?","`SequencedSet\u003CE>` extends both `SequencedCollection\u003CE>` and `Set\u003CE>`,\nadding no new methods but guaranteeing both the set contract (no\nduplicates) and a defined encounter order.\n\nImplementing classes:\n- `LinkedHashSet` — insertion-ordered set, implements `SequencedSet`\n- `SortedSet` subtypes: `TreeSet` — sorted, implements `SequencedSet`\n  via `SortedSet` (which extends `SequencedSet`)\n\n```java\nSequencedSet\u003CString> set = new LinkedHashSet\u003C>(List.of(\"b\", \"a\", \"c\"));\nSystem.out.println(set.getFirst()); \u002F\u002F \"b\" — insertion order\nSystem.out.println(set.getLast());  \u002F\u002F \"c\"\nSystem.out.println(set.reversed()); \u002F\u002F [\"c\", \"a\", \"b\"] — reversed view\n```\n\n**Rule of thumb:** `SequencedSet` lets you treat `LinkedHashSet` and\n`TreeSet` uniformly when you need first\u002Flast\u002Freversed without knowing\nthe concrete type.\n",{"id":36,"difficulty":37,"q":38,"a":39},"sequenced-map-interface","medium","What is SequencedMap and what methods does it add?","`SequencedMap\u003CK,V>` extends `Map\u003CK,V>` and adds methods to access\nthe first and last entries:\n\n| Method | Description |\n|---|---|\n| `firstEntry()` | Returns (but does not remove) the first `Map.Entry` |\n| `lastEntry()` | Returns the last `Map.Entry` |\n| `pollFirstEntry()` | Removes and returns the first entry |\n| `pollLastEntry()` | Removes and returns the last entry |\n| `putFirst(K, V)` | Inserts\u002Fmoves entry to the front (optional) |\n| `putLast(K, V)` | Inserts\u002Fmoves entry to the back (optional) |\n| `reversed()` | Returns a reversed-order map view |\n| `sequencedKeySet()` | Returns a `SequencedSet\u003CK>` |\n| `sequencedValues()` | Returns a `SequencedCollection\u003CV>` |\n| `sequencedEntrySet()` | Returns a `SequencedSet\u003CMap.Entry\u003CK,V>>` |\n\n```java\nSequencedMap\u003CString, Integer> map = new LinkedHashMap\u003C>();\nmap.put(\"a\", 1); map.put(\"b\", 2); map.put(\"c\", 3);\n\nSystem.out.println(map.firstEntry()); \u002F\u002F a=1\nSystem.out.println(map.lastEntry());  \u002F\u002F c=3\n\nmap.putFirst(\"z\", 0);                \u002F\u002F {z=0, a=1, b=2, c=3}\n```\n\n**Rule of thumb:** `SequencedMap` lets you use `LinkedHashMap` and\n`TreeMap` with a uniform first\u002Flast\u002Freversed API without casting.\n",{"id":41,"difficulty":14,"q":42,"a":43},"which-collections-implement","Which existing Java collections implement the new sequenced interfaces?","The new interfaces are retrofitted onto the existing type hierarchy:\n\n| Collection | Implements |\n|---|---|\n| `ArrayList`, `LinkedList`, `ArrayDeque` | `SequencedCollection` |\n| `LinkedHashSet` | `SequencedSet` |\n| `TreeSet` | `SequencedSet` (via `SortedSet`) |\n| `LinkedHashMap` | `SequencedMap` |\n| `TreeMap` | `SequencedMap` (via `SortedMap`) |\n| `List` (interface) | `SequencedCollection` |\n| `Deque` (interface) | `SequencedCollection` |\n| `SortedSet` (interface) | `SequencedSet` |\n| `SortedMap` (interface) | `SequencedMap` |\n\n```java\nSequencedCollection\u003CInteger> col = new ArrayDeque\u003C>(List.of(1, 2, 3));\ncol.getFirst(); \u002F\u002F 1\ncol.getLast();  \u002F\u002F 3\n```\n\n**Rule of thumb:** if the concrete type is `ArrayList`, `LinkedHashSet`,\n`TreeMap`, etc. you already have the new methods — no migration needed.\n",{"id":45,"difficulty":37,"q":46,"a":47},"reversed-method","What does the reversed() method return?","`reversed()` returns a **live, write-through view** of the collection in\nreverse encounter order. Mutations through the reversed view are reflected\nin the original, and vice versa.\n\n```java\nList\u003CString> list = new ArrayList\u003C>(List.of(\"a\", \"b\", \"c\"));\nList\u003CString> rev  = list.reversed();\n\nSystem.out.println(rev);   \u002F\u002F [c, b, a]\n\nrev.addFirst(\"z\");         \u002F\u002F adds to the reversed view's front\nSystem.out.println(list);  \u002F\u002F [a, b, c, z]  — \"z\" is at the END of original\n\nlist.add(\"x\");             \u002F\u002F adds to original\nSystem.out.println(rev);   \u002F\u002F [x, z, c, b, a] — reflected in reversed view\n```\n\n**Rule of thumb:** `reversed()` is a live view, not a copy — mutations\npropagate both ways; if you need an independent copy, copy it explicitly.\n",{"id":49,"difficulty":14,"q":50,"a":51},"list-getfirst-vs-get0","Is list.getFirst() just a synonym for list.get(0)?","For `List` implementations, `getFirst()` is equivalent to `get(0)` except\nfor the exception when the list is empty. `get(0)` throws\n`IndexOutOfBoundsException`; `getFirst()` throws `NoSuchElementException`.\n\n```java\nList\u003CString> empty = new ArrayList\u003C>();\n\nempty.get(0);      \u002F\u002F IndexOutOfBoundsException: Index 0 out of bounds\nempty.getFirst();  \u002F\u002F NoSuchElementException\n\nList\u003CString> list = List.of(\"a\", \"b\", \"c\");\nlist.get(0);       \u002F\u002F \"a\"\nlist.getFirst();   \u002F\u002F \"a\" — same result\n```\n\nThe semantic difference: `IndexOutOfBoundsException` signals a programming\nerror (index miscalculation); `NoSuchElementException` signals an empty\ncollection. `getFirst()` better expresses intent.\n\n**Rule of thumb:** prefer `getFirst()` \u002F `getLast()` over `get(0)` and\n`get(size-1)` — the intent is clearer and the exception type is more\nsemantically correct.\n",{"id":53,"difficulty":37,"q":54,"a":55},"sequenced-vs-deque","How does SequencedCollection relate to Deque?","`Deque` already had `peekFirst()`\u002F`peekLast()`, `pollFirst()`\u002F`pollLast()`,\n`addFirst()`\u002F`addLast()`. The new `SequencedCollection` essentially makes\nthese methods available on all ordered collections uniformly:\n\n| Deque method | SequencedCollection equivalent |\n|---|---|\n| `peekFirst()` | `getFirst()` |\n| `peekLast()` | `getLast()` |\n| `pollFirst()` | `removeFirst()` |\n| `pollLast()` | `removeLast()` |\n| `addFirst(e)` | `addFirst(e)` |\n| `addLast(e)` | `addLast(e)` |\n\nDeque itself now extends `SequencedCollection`, so `ArrayDeque` and\n`LinkedList` implement both and can be used interchangeably with either API.\n\n**Rule of thumb:** `Deque` and `SequencedCollection` now share the first\u002F\nlast API — prefer `SequencedCollection` in method signatures when you don't\nneed `Deque`-specific operations like `push()`\u002F`pop()`.\n",{"id":57,"difficulty":37,"q":58,"a":59},"unmodifiable-sequenced","Do Collections.unmodifiableList() and List.of() support SequencedCollection?","Yes. `List` now extends `SequencedCollection`, so all `List` instances —\nincluding `List.of()` (immutable), `Collections.unmodifiableList()`, and\n`Arrays.asList()` — have `getFirst()`\u002F`getLast()`:\n\n```java\nList\u003CString> immutable = List.of(\"a\", \"b\", \"c\");\nSystem.out.println(immutable.getFirst()); \u002F\u002F \"a\" — works fine\nSystem.out.println(immutable.getLast());  \u002F\u002F \"c\"\n\n\u002F\u002F Mutation methods throw UnsupportedOperationException on immutable lists:\nimmutable.addFirst(\"z\"); \u002F\u002F UnsupportedOperationException\n```\n\n**Rule of thumb:** `getFirst()`\u002F`getLast()` are safe on any `List`,\nincluding immutable ones; mutation methods follow the same modifiability\nrules as before.\n",{"id":61,"difficulty":14,"q":62,"a":63},"before-java21-workarounds","What were the workarounds for getting first\u002Flast elements before Java 21?","Each collection type needed a different API:\n\n```java\n\u002F\u002F List — verbose index arithmetic:\nString first = list.get(0);\nString last  = list.get(list.size() - 1);\n\n\u002F\u002F LinkedList (as Deque) — dedicated methods:\nString first = ((LinkedList\u003CString>) list).getFirst();\n\n\u002F\u002F ArrayDeque:\nString first = deque.peekFirst();\nString last  = deque.peekLast();\n\n\u002F\u002F SortedSet \u002F TreeSet:\nString first = sortedSet.first();\nString last  = sortedSet.last();\n\n\u002F\u002F Iterating in reverse — no unified API:\nCollections.reverse(list); \u002F\u002F mutates the list!\n\u002F\u002F Or:\nListIterator\u003CString> it = list.listIterator(list.size());\nwhile (it.hasPrevious()) System.out.println(it.previous());\n```\n\n`SequencedCollection` replaces all of these with `getFirst()`, `getLast()`,\nand `reversed()`.\n\n**Rule of thumb:** if you wrote `list.get(list.size()-1)` before Java 21,\nreplace it with `list.getLast()` — it is shorter and communicates intent.\n",{"id":65,"difficulty":37,"q":66,"a":67},"sequenced-in-method-signatures","When should you use SequencedCollection as a method parameter type?","Use `SequencedCollection\u003CE>` (or `SequencedMap\u003CK,V>`) in method signatures\nwhen your method **specifically needs first\u002Flast access or reverse\niteration** but doesn't need to know the concrete type:\n\n```java\n\u002F\u002F Accept any ordered collection with first\u002Flast semantics:\nstatic \u003CT> T middle(SequencedCollection\u003CT> col) {\n    \u002F\u002F Use getFirst\u002FgetLast without caring if it's ArrayList or LinkedHashSet\n    if (col.isEmpty()) throw new NoSuchElementException();\n    \u002F\u002F ... navigate to middle via iterator\n}\n\n\u002F\u002F Too narrow — only works for List:\nstatic \u003CT> T middle(List\u003CT> list) { ... }\n\n\u002F\u002F Too broad — Collection doesn't guarantee order:\nstatic \u003CT> T middle(Collection\u003CT> col) { ... } \u002F\u002F getFirst() doesn't exist\n```\n\n**Rule of thumb:** prefer `SequencedCollection` over `List` in signatures\nwhen order and first\u002Flast access matter but random index access (`get(i)`)\ndoes not.\n",11,null,{"description":11},"Java sequenced collections interview questions — SequencedCollection, SequencedSet, SequencedMap, getFirst\u002FgetLast, addFirst\u002FaddLast, reversed(), which collections implement the new interfaces, and migration from workarounds.","java\u002Fmodern-java\u002Fsequenced-collections","Modern Java","modern-java","2026-06-20","Aswq8TvLa3y5unPRdSW-X5Ypb8giKFStzLf2q6t9AmY",[78,82,85,89,93,97,101,105],{"subtopic":79,"path":80,"order":81},"Records","\u002Fjava\u002Fmodern-java\u002Frecords",1,{"subtopic":83,"path":84,"order":12},"Sealed Classes","\u002Fjava\u002Fmodern-java\u002Fsealed-classes",{"subtopic":86,"path":87,"order":88},"Switch Pattern Matching","\u002Fjava\u002Fmodern-java\u002Fswitch-pattern-matching",3,{"subtopic":90,"path":91,"order":92},"Text Blocks","\u002Fjava\u002Fmodern-java\u002Ftext-blocks",4,{"subtopic":94,"path":95,"order":96},"instanceof Pattern Matching","\u002Fjava\u002Fmodern-java\u002Finstanceof-pattern-matching",5,{"subtopic":98,"path":99,"order":100},"Virtual Threads","\u002Fjava\u002Fmodern-java\u002Fvirtual-threads",6,{"subtopic":102,"path":103,"order":104},"Record Patterns","\u002Fjava\u002Fmodern-java\u002Frecord-patterns",7,{"subtopic":6,"path":21,"order":20},{"path":107,"title":108},"\u002Fblog\u002Fjava-sequenced-collections","Java Sequenced Collections — getFirst, getLast, and reversed() for Every Ordered Type",1782244117729]