Computer scienceProgramming languagesJavaWorking with dataCollectionsCollection implementationsSequenced collections

Introduction to Sequenced Collections

13 minutes read

Java’s Collections Framework has long provided powerful abstractions for grouping and managing data. Yet, before JDK 21, there was no single interface to represent all ordered collections uniformly. List, Deque, and LinkedHashSet each provide their mechanisms for front- and back-end operations. Still, the lack of a unified interface has made it difficult to write generic algorithms that can operate seamlessly across all ordered collection types. For example, List uses get(0) to retrieve the first element, Deque uses getFirst(), and LinkedHashSet has no direct method to access the first or last element. This inconsistency made it cumbersome to write reusable, order-aware code that could work generically with any ordered collection.

JEP 431 introduces Sequenced Collections to address these inconsistencies by providing a clear contract for ordered collections with dedicated methods for bidirectional access. These interfaces are retrofitted into the existing hierarchy. As a result, popular classes like LinkedList, ArrayDeque, LinkedHashSet, and LinkedHashMap automatically gain new sequencing capabilities without any code changes.

Key concepts and features

A sequenced collection is any collection that guarantees an encounter order, meaning each element has a defined predecessor and successor (except at the ends). Three new interfaces were introduced to standardize ordered behavior across lists, sets, and maps. With these, developers benefit from consistent access patterns, improved API cohesion, and better reusability. With these new interfaces, you can:

  • Guarantee a clear first and last element in any ordered collection.

  • Invoke consistent methods to add, access, or remove elements at both ends.

  • Use lists that preserve insertion order, although they previously lacked efficient methods to modify both ends.

  • Work with deques that support front and end operations, even though they are primarily designed for queue-like behavior.

  • Handle sets more predictably: while HashSet does not preserve order, LinkedHashSet does, but only now with a standardized interface like SequencedSet to enforce that order consistently.

Sequenced collection

SequencedCollection<E> extends Collection<E> and adds a standardized set of methods for accessing and manipulating the elements at both the beginning and the end of the collection. These include addFirst(), addLast(), getFirst(), getLast(), removeFirst(), removeLast(), and reversed(). This provides a uniform mechanism for handling any collection that maintains a defined order of encounters. The following UML diagram shows the structure and methods of the SequencedCollection<E> interface.

A diagram representing a Sequenced Collection

Sequenced set

SequencedSet<E> extends both Set<E> and SequencedCollection<E>. It retains the uniqueness constraints of a typical set while also preserving insertion order. A key enhancement is the covariant override of the reversed() method, which ensures that the reversed view is also a SequencedSet<E> collection rather than a generic collection. This allows developers to maintain both type safety and ordering semantics while working with ordered sets. The diagram below illustrates the methods defined in the SequencedSet<E> interface.

A diagram representing a Sequenced Set

Sequenced map

SequencedMap<K, V> extends Map<K, V> by providing ordered views for the map’s keys, values, and entry sets. This means you can now treat a Map not just as a key-value store, but as a sequence with predictable and manipulable order. With SequencedMapoperations like inserting or removing entries from either end, or iterating in reverse order, becoming natively supported, making it ideal for use cases like time-stamped logs, ordered caches, or queue-backed maps. The following UML diagram presents the methods provided by the SequencedMap<K, V> interface.

A diagram representing a Sequenced Map

Retrofitting

These newly added interfaces fit naturally within the existing Java Collection hierarchy, extending the capabilities of familiar types without altering their core structure. The following image illustrates the updated hierarchy.

Class hierarchy diagram for collections and maps.

These interfaces were seamlessly integrated into existing collection types, allowing widely used classes to support sequencing behavior without requiring structural changes. In particular:

  • The List interface now directly extends SequencedCollection, aligning all list implementations with the new sequencing contract.

  • The Deque interface also extends SequencedCollection, making double-ended queues part of the sequenced family.

  • LinkedHashSet, which preserves insertion order, now implements SequencedSet, granting it standardized access to the first and last elements.

  • SortedSet has been updated to extend SequencedSet, ensuring that all sorted set implementations gain sequencing behavior in addition to their ordering.

  • LinkedHashMap, known for maintaining insertion order among entries, now implements SequencedMap, enabling it to support sequencing operations.

  • SortedMap has similarly been modified to extend SequencedMap, integrating sequencing capabilities alongside key-based sorting.

These enhancements ensure that the benefits of sequencing, like consistent end-based operations and predictable iteration, are universally available across all major ordered collection types in Java.

Why sequenced interfaces matter

Sequenced collections offer several practical and architectural benefits within the Java Collections Framework. By bringing consistent behavior and operations to all ordered collections, they simplify programming and enhance code clarity. The following are some reasons why sequenced collections are instrumental:

  • Sequenced interfaces unify the way we interact with ordered collections. Instead of relying on multiple interfaces like List and Deque—each with its method set—developers now have a single, standardized contract for working with any ordered collection. This reduces cognitive load and simplifies code that needs to operate generically over different ordered types.

  • All sequencing methods, such as addFirst(), getLast(), and reversed() are provided as default methods in the interfaces. This means that classes like LinkedList, ArrayDeque, and LinkedHashSet automatically inherit and support these features without requiring any changes in their source code, promoting backward compatibility and smoother transitions.

  • Sequenced collections offer a built-in reversed() method that returns a view of the collection in the opposite order. This makes it trivial to iterate from end to start, without manually reversing the collection or using additional data structures. Such traversal is crucial in many algorithms that require backtracking or reverse processing.

  • One of the strengths of JEP 431 lies in its retrofit-friendly approach. The new interfaces were carefully designed to fit into the existing type hierarchy, meaning developers can take advantage of the new features with minimal disruption to legacy code. You can start using sequenced methods immediately on classes you already use while maintaining full compatibility with previous versions of your codebase.

Core sequencing methods

Rather than learning different method names across types, JEP 431 gives every sequenced interface the same set of operations at both ends. These ship as default methods, so your code can call them on any implementing class.

Operation

Purpose

addFirst(E e)

Insert an element at the start of the collection

addLast(E e)

Insert an element at the end of the collection

getFirst()

Retrieve (but do not remove) the first element

getLast()

Retrieve (but do not remove) the last element

removeFirst()

Remove and return the first element

removeLast()

Remove and return the last element

reversed()

Return a view of the same collection in reverse

Note: These methods are available on all sequenced types, including lists, deques, and sets (where applicable).

Collections utility methods for sequenced types

To complement the new interfaces introduced with JEP 431, the java.util.Collections class has been extended with new utility methods. These additions are important for cases where you want to share a collection while ensuring its contents remain unmodifiable, yet still preserve the encounter order guaranteed by sequenced interfaces.

In earlier versions of Java, creating unmodifiable collections typically involved methods like Collections.unmodifiableList() or Collections.unmodifiableSet(). While useful, these methods did not provide sequencing guarantees unless applied to a type that happened to maintain insertion order, such as LinkedHashSet. The new methods in JDK 21 ensure that both immutability and sequence order are explicitly respected and enforced.

The following new methods are available:

  • Collections.unmodifiableSequencedCollection(SequencedCollection<E>): Wraps any SequencedCollection to create a read-only version while maintaining first/last ordering.

  • Collections.unmodifiableSequencedSet(SequencedSet<E>): Applies the same immutability to ordered sets, preserving set semantics and encounter order.

  • Collections.unmodifiableSequencedMap(SequencedMap<K, V>): Returns a map view where the keys, values, and entries maintain their insertion order, and no modifications are allowed.

These methods are particularly useful when returning data structures from APIs that consumers must not change. For example, an ordered set of configuration keys or a time-ordered map of events can be exposed in an unmodifiable form, ensuring both safety and predictability.

Note: The unmodifiable wrappers throw UnsupportedOperationException on any attempt to modify the returned view, such as adding or removing elements.

Handling exceptions in sequenced collections

As with many collection operations in Java, certain edge cases can result in runtime exceptions. Understanding when these exceptions may arise helps ensure your code is both safe and predictable. While working with sequenced collections, it’s important to be aware of potential exceptions:

  • UnsupportedOperationException: This is thrown when attempting to modify an unmodifiable sequenced collection created using methods like Collections.unmodifiableSequencedCollection(). Any call to modifying methods such as addFirst(), addLast(), putFirst(), or putLast() on these wrappers will result in this exception, as the underlying structure is explicitly read-only. The same applies to sorted collections because they determine element order using natural ordering or a comparator, allowing insertion at a specific position would violate their ordering.

  • NoSuchElementException: This is thrown when trying to access elements (e.g., getFirst() or removeLast()) from an empty sequenced collection. Always ensure the collection is not empty before performing such operations.

Conclusion

Sequenced interfaces bring clarity and consistency to working with ordered collections in Java. Introducing SequencedCollection, SequencedSet, and SequencedMapJEP 431 provides a unified approach to handling encounter-ordered collections, helping developers work with ordered collections more intuitively and flexibly. With minimal changes to existing classes and the addition of helpful utility methods, these updates simplify development by reducing boilerplate code and enabling consistent behavior across collection types. The retrofit strategy ensures smooth integration with existing APIs and legacy systems, making adoption both easy and beneficial.

2 learners liked this piece of theory. 1 didn't like it. What about you?
Report a typo