Sequenced Collections (Java 21) — first, last, reversed — Finally
Fast recall
Quick revision
Core answer
getFirst(), getLast(), addFirst(e), addLast(e), removeFirst(), removeLast(), and reversed() (returning a reversed view, not a copy). Before Java 21, this was a mess: List had get(0) and get(list.size() - 1), Deque had getFirst/getLast, LinkedHashSet had no built-in first/last, and SortedSet had first/last but different semantics. The inheritance is retroactive: List now extends SequencedCollection, Deque extends SequencedCollection, LinkedHashSet implements SequencedSet, SortedSet implements SequencedSet, and LinkedHashMap/SortedMap implement SequencedMap. The reversed() method is a view (O(1) construction, lazy iteration), not a copy. ArrayList.reversed() iterates backward without allocating; same for the others. SequencedMap also adds firstEntry(), lastEntry(), sequencedKeySet(), sequencedValues(), and sequencedEntrySet() — the latter three return views over the map that preserve encounter order and support their own reverse iteration. Primary value: consistency. No more remembering which collection has getFirst vs get(0) vs peekFirst. For APIs that care about order (caches, LRU, insertion-ordered maps), this is a long-overdue cleanup.Whether the candidate knows the new interfaces, the retrofit onto existing classes, the view semantics of reversed(), and the specific new methods on SequencedMap
Thinking `reversed()` returns a copy (it returns a view). Not knowing `SequencedSet` vs `SequencedCollection`. Missing that `SortedSet` is now a `SequencedSet`
Discuss the retrofit challenge (how they added interfaces to existing final APIs), mention the `SequencedMap.firstEntry()` returning unmodifiable entries, and explain why sets without order (HashSet) don't implement SequencedSet
Interview-ready guide
Interview answer
Sequenced collections (Java 21, JEP 431) add three new interfaces that formalize 'a collection with a well-defined encounter order' and give Java a uniform API for first/last access and reverse iteration.
The three interfaces
`SequencedCollection
getFirst(),getLast()addFirst(e),addLast(e)removeFirst(),removeLast()reversed()— returns a view
`SequencedSetSequencedCollection + Set
- Adopted by
LinkedHashSetandSortedSet
`SequencedMap
firstEntry(),lastEntry()putFirst(k, v),putLast(k, v)pollFirstEntry(),pollLastEntry()reversed()sequencedKeySet(),sequencedValues(),sequencedEntrySet()
Motivation
Pre-Java 21, there was a mess:
List.get(0)vsDeque.getFirst()vsLinkedHashSet.iterator().next()vsSortedSet.first()- No built-in
last()forLinkedHashSetorLinkedHashMap - Reverse iteration was a different API per collection
Sequenced collections unify all this.
Retrofit via default methods
Now implement Sequenced\*
List(ArrayList, LinkedList) —SequencedCollectionDeque(ArrayDeque) —SequencedCollectionLinkedHashSet,SortedSet/TreeSet—SequencedSetLinkedHashMap,SortedMap/TreeMap—SequencedMap
Do NOT implement
HashSet,HashMap,ConcurrentHashMap— no defined orderPriorityQueue— iteration order doesn't match priority order
Possible because default method implementations in the interfaces mean no class needs modification; subclasses override for efficiency.
`reversed()` is a view, not a copy
- O(1) construction, no allocation
- Lazy iteration in reverse order
- Mutations to original reflect in view and vice versa
- If you want a true reversed copy:
new ArrayList<>(list.reversed()) - Compare with
Collections.reverse(list)which mutates the original
LRU cache pattern is now idiomatic
LinkedHashMap+putLast(key, value)+pollFirstEntry()for eviction- Before Java 21, you had to use the
accessOrderconstructor argument — clunky
Empty behavior
getFirst/getLastthrowNoSuchElementExceptionon empty- Different from
Deque.peekFirst/peekLast(return null) - Check
isEmpty()first or use try/catch
Immutable collections work too
List.of(a, b, c).getFirst()returnsalist.addFirst(...)throwsUnsupportedOperationExceptionon immutableList.of(a, b, c).reversed()returns an immutable reversed view
Practical improvements
Cleaner code everywhere:
list.getFirst()beatslist.get(0)— intent is clearlist.getLast()beatslist.get(list.size() - 1)— less risk of buglhm.firstEntry()on LinkedHashMap was previously impossible without iteration
Reverse iteration for free:
LinkedHashSet.reversed()— iterate newest-to-oldestLinkedHashMap.reversed()— same for maps- Previously required copying to a list and reversing
APIs can require ordering:
- Methods can accept
SequencedMapinstead ofMap - Forces the caller to use an ordered map
- Better than runtime assertions about encounter order
Caveats
1. Not all collections qualify — HashMap, HashSet, ConcurrentHashMap, PriorityQueue don't
2. `reversed()` is a view — mutations propagate
3. Empty collection throws NoSuchElementException — always check size
4. Immutable collections — mutating methods throw UOE
5. sequencedEntrySet() — different from entrySet(); returns a SequencedSet with reverse support
No breaking changes
- Old code works unchanged
- New methods added via default methods
- Adopt incrementally
Recommendation: Start using `getFirst()`, `getLast()`, `addFirst()`, `addLast()` as your default for List, Deque, LinkedHashSet, and LinkedHashMap — the intent is clearer than get(0) or iterator().next(). For LRU caches on LinkedHashMap, the putLast + pollFirstEntry pattern replaces the old accessOrder constructor trick — cleaner and more explicit. Remember `reversed()` is a view, not a copy: O(1) construction, mutations propagate both ways; copy with new ArrayList<>(list.reversed()) if you need independence. Watch the empty collection trap — getFirst/getLast throw NoSuchElementException, unlike Deque.peekFirst which returns null. When designing APIs, accept `SequencedMapMap or Collection when you care about encounter order — you get compile-time enforcement. And note which collections don't implement these: HashMap, HashSet, ConcurrentHashMap, PriorityQueue — because they genuinely lack a defined order. This is a small, well-scoped API addition but one of the most universally useful — you'll use it every day.
Sequenced Collections (Java 21) — `first`, `last`, `reversed` — Finally
Direct Answer
Sequenced collections (Java 21, JEP 431) add three new interfaces — SequencedCollection<E>, SequencedSet<E>, SequencedMap<K, V> — that formalize the concept of 'a collection with a well-defined encounter order.' They add a uniform API for accessing the first/last element and iterating in reverse: getFirst(), getLast(), addFirst(e), addLast(e), removeFirst(), removeLast(), and reversed() (returning a reversed view, not a copy). Before Java 21, this was a mess: List had get(0) and get(list.size() - 1), Deque had getFirst/getLast, LinkedHashSet had no built-in first/last, and SortedSet had first/last but different semantics. The inheritance is retroactive: List now extends SequencedCollection, Deque extends SequencedCollection, LinkedHashSet implements SequencedSet, SortedSet implements SequencedSet, and LinkedHashMap/SortedMap implement SequencedMap. The reversed() method is a view (O(1) construction, lazy iteration), not a copy. ArrayList.reversed() iterates backward without allocating; same for the others. SequencedMap also adds firstEntry(), lastEntry(), sequencedKeySet(), sequencedValues(), and sequencedEntrySet() — the latter three return views over the map that preserve encounter order and support their own reverse iteration. Primary value: consistency. No more remembering which collection has getFirst vs get(0) vs peekFirst. For APIs that care about order (caches, LRU, insertion-ordered maps), this is a long-overdue cleanup.
Common Mistakes & Pitfalls
Thinking reversed() returns a copy (it returns a view). Not knowing SequencedSet vs SequencedCollection. Missing that SortedSet is now a SequencedSet
Check your understanding
Answer these without looking back at the article.
- Is `list.reversed()` a view or a copy?
- Why doesn't `HashMap` implement `SequencedMap`?
- How does `LinkedHashMap.putLast` enable LRU caches?
- What's the difference between `entrySet()` and `sequencedEntrySet()`?
- What exception does `getFirst()` throw on an empty list?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.