JEP 431: Sequenced Collections has been promoted from Candidate to Proposed to Target status for JDK 21. It proposes introducing "a new family of interfaces that represent the concept of a collection whose elements are arranged in a well-defined sequence or ordering, as a structural property of the collection." This is motivated by the need for a well-defined ordering and a uniform set of operations within the Collections Framework.
Java's collections framework has long needed a collection type that represents a sequence of elements with a defined encounter order and a uniform set of operations that apply across such collections. Unfortunately, support for encounter order is currently spread across the type hierarchy, making expressing certain practical concepts in APIs difficult. In response, a proposal has been proposed to introduce new interfaces to represent collections with a defined encounter order and provide uniform APIs for accessing their first and last elements and processing them in reverse order.
The lack of a collection type representing a sequence of elements with a defined encounter order has been a repeated source of problems and complaints. For example, while List
and Deque
define an encounter order, their common supertype is Collection
, which does not. Similarly, Set
does not specify an encounter order, and subtypes such as HashSet
do not define one, but subtypes such as SortedSet
and LinkedHashSet
do.
To address this issue, new interfaces have been defined for sequenced collections, sequenced sets, and sequenced maps and then retrofitted into the existing collection’s type hierarchy. All of the new methods declared in these interfaces have default implementations. Sequenced collections, sets, and maps all have different characteristics, with sequenced collections representing a collection whose elements have a defined encounter order, sequenced sets representing a set that is a sequenced collection that contains no duplicate elements, and sequenced maps representing a map whose entries have a defined encounter order.
The new reversed()
method provides a reverse-ordered view of the original collection, enabling all the different sequenced types to process elements in both directions using all the usual iteration mechanisms, such as enhanced for loops, explicit iterator()
loops, forEach()
, stream()
, parallelStream()
, and toArray()
.
The SequencedCollection
interface includes several new methods, as follows::
interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}
The SequencedSet
interface includes the same methods as SequencedCollection
, plus reversed()
. Finally, the SequencedMap
interface includes several new methods, as follows:
interface SequencedMap<K,V> extends Map<K,V> {
// new methods
SequencedMap<K,V> reversed();
SequencedSet<K> sequencedKeySet();
SequencedCollection<V> sequencedValues();
SequencedSet<Entry<K,V>> sequencedEntrySet();
V putFirst(K, V);
V putLast(K, V);
// methods promoted from NavigableMap
Entry<K, V> firstEntry();
Entry<K, V> lastEntry();
Entry<K, V> pollFirstEntry();
Entry<K, V> pollLastEntry();
}
All three new interfaces fit neatly into the existing collections type hierarchy, with List
having SequencedCollection
as its immediate superinterface, Deque
having SequencedCollection
as its immediate superinterface, LinkedHashSet
implementing SequencedSet
, SortedSet
having SequencedSet
as its immediate superinterface, LinkedHashMap
implementing SequencedMap
, and SortedMap
having SequencedMap
as its immediate superinterface.
While explicit-positioning APIs such as SortedSet::addFirst
and SortedMap::putLast
throw UnsupportedOperationException
because the sequence of their elements is determined by relative comparison, the asymmetry of having some collections not implement all of the SequencedCollection
operations is valuable because it brings SortedSet
and SortedMap
into the sequenced collection family, allowing them to be used more broadly than otherwise.
Overall, introducing new interfaces to represent collections with a defined encounter order and a uniform set of operations that apply across such collections is a significant step forward for Java's Collections Framework. By providing support for encounter order in a consistent and easy-to-use manner, the framework will become more intuitive and efficient for developers.