Modern Java

40. Sequenced Collections

Java 21 introduced SequencedCollection, SequencedSet, and SequencedMap โ€” new interfaces that give all ordered collections a uniform API for accessing and modifying the first and last elements.

Java 21+ (standard)

Explanation

Before Java 21, accessing the first/last element of a collection required ugly workarounds: list.get(0), list.get(list.size()-1), linkedHashSet.iterator().next(). There was no uniform API. SequencedCollection (JEP 431) fills this gap.

SequencedCollection<E> extends Collection and adds: getFirst(), getLast(), addFirst(e), addLast(e), removeFirst(), removeLast(), and reversed() (returns a view with the iteration order reversed). ArrayList, LinkedList, ArrayDeque all implement it.

SequencedSet<E> extends SequencedCollection and Set. LinkedHashSet and TreeSet implement it. SequencedMap<K,V> extends Map and adds firstEntry(), lastEntry(), pollFirstEntry(), pollLastEntry(), putFirst(), putLast(), and reversed(). LinkedHashMap and TreeMap implement it.

Example

import java.util.*;

public class SequencedCollections {
    public static void main(String[] args) {
        // SequencedCollection โ€” List implements it
        SequencedCollection<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));

        System.out.println("First: " + list.getFirst()); // a
        System.out.println("Last:  " + list.getLast());  // d

        list.addFirst("START");
        list.addLast("END");
        System.out.println("After additions: " + list); // [START, a, b, c, d, END]

        list.removeFirst();
        list.removeLast();
        System.out.println("After removals:  " + list); // [a, b, c, d]

        // reversed() โ€” view, not a copy
        System.out.println("Reversed: " + list.reversed()); // [d, c, b, a]

        // SequencedSet โ€” LinkedHashSet
        SequencedSet<Integer> set = new LinkedHashSet<>(List.of(1, 2, 3, 4));
        System.out.println("Set first: " + set.getFirst()); // 1
        System.out.println("Set last:  " + set.getLast());  // 4
        System.out.println("Reversed set: " + set.reversed());

        // SequencedMap โ€” LinkedHashMap
        SequencedMap<String, Integer> map = new LinkedHashMap<>();
        map.put("one", 1); map.put("two", 2); map.put("three", 3);
        System.out.println("First entry: " + map.firstEntry()); // one=1
        System.out.println("Last entry:  " + map.lastEntry());  // three=3
        map.putFirst("zero", 0);
        System.out.println("After putFirst: " + map);
    }
}

Sources