Files

sequenced

Companion code for the ankurm.com post "Sequenced Collections in Java 21+: getFirst, getLast and reversed()." Module in java-core-examples, the Java-core series.

Versions this was built and tested against

Component Version Notes
JDK 25.0.4.1+1 (Temurin, LTS) JEP 431 shipped in JDK 21 (GA September 2023) and is unchanged since.
JUnit Jupiter 5.11.0
Maven 3.9.11

Quickstart

export JAVA_HOME=/path/to/jdk-21-or-newer
mvn compile
java -cp target/classes com.ankurm.sequenced.AcrossCollectionsDemo
java -cp target/classes com.ankurm.sequenced.FindLastDemo
java -cp target/classes com.ankurm.sequenced.ReversedViewIsLiveDemo

scripts/run-all.sh regenerates every file in output/. scripts/run.sh <ClassName> runs one demo ad hoc.

What's in here

File What it shows
src/main/java/.../AcrossCollectionsDemo.java getFirst/getLast/addFirst/addLast/reversed() run against ArrayList, ArrayDeque, LinkedHashSet, LinkedHashMap and TreeMap - the one shared contract across five previously-unrelated types.
src/main/java/.../FindLastDemo.java The three pre-Java-21 ways people found "the last element" of a Set (two stream tricks and a throwaway copy) next to the one-line getLast() replacement, with a note on why the old ways cost more than they looked like they did.
src/main/java/.../ReversedViewIsLiveDemo.java reversed() is a live view, not a copy - mutating either side is visible through the other, immediately.
src/test/java/.../SequencedCollectionsTest.java Pins all of the above as assertions, 6/6 passing.
output/00-javap-sequenced-interfaces.txt javap output for SequencedCollection, SequencedMap, SequencedSet straight from the compiled JDK - the primary-source check this repo's discipline requires before describing any interface's method list.
output/01-04 Captured runs of the three demos and the test suite.

Notes worth knowing before reading the post

  • TreeMap/TreeSet already had most of this. firstEntry()/lastEntry()/pollFirstEntry()/pollLastEntry() existed on NavigableMap since Java 6; what JEP 431 adds for sorted collections is mostly reversed() as a named counterpart to descendingMap()/descendingSet(), plus the shared interface. The real new capability lands on LinkedHashSet and LinkedHashMap, which had an iteration order but no vocabulary for "first" or "last" before this.
  • reversed() is a view. See output/03 - mutating the original after taking reversed() is visible through the view and vice versa. This is the most common assumption bug the feature produces.
  • LinkedHashSet.getLast() is O(1) in practice, not by interface contract - it resolves through SequencedCollection's default method path to the reversed view's first element, and LinkedHashSet/LinkedHashMap already maintain a doubly-linked insertion-order list internally, so there's no O(n) walk. That is an implementation detail of the JDK's LinkedHashMap, not a guarantee SequencedCollection itself makes for arbitrary implementors.

License

MIT - see the repo-wide LICENSE.