# 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 ```bash 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 ` 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](../LICENSE).