CodeGym /Courses /JAVA 25 SELF /New collections: SequencedCollection, SequencedSet, Seque...

New collections: SequencedCollection, SequencedSet, SequencedMap

JAVA 25 SELF
Level 34 , Lesson 4
Available

1. The problem of order in classic collections

Java has always had collections that guarantee element order (for example, ArrayList, LinkedList, LinkedHashSet, LinkedHashMap), and others where order is not guaranteed (for example, HashSet, HashMap). But all of these collections had one common drawback: despite some of them storing elements in a specific order, the standard interfaces (List, Set, Map) did not provide universal methods to access the first and last elements or to reverse the order.

For example, if you have a List<String>, you can get the first element via list.get(0), but for a Set or a Map that trick won’t work — you’ll have to use iterators or write extra code. It’s not very convenient and doesn’t help readability.

It’s like having a cabinet with drawers, but to pull out the first or last drawer you had to recount all of them by hand every time! It would be great to have special handles “first” and “last,” right?

The arrival of SequencedCollection and related interfaces

New collection interfaces appeared in Java 21:

  • SequencedCollection<E>
  • SequencedSet<E>
  • SequencedMap<K, V>

These interfaces extend the standard collections and introduce a unified approach to working with element order. Now you can write universal code for any collections where order matters, without worrying about the specific implementation.

What are these?

  • SequencedCollection is a collection whose elements have a specific order; you can easily get the first and last element and also reverse the order.
  • SequencedSet is the same, but for sets (unique elements).
  • SequencedMap is the same, but for maps (key–value).

Which collections implement them now?

In Java 21, the new interfaces are implemented by the following standard collections:

  • ArrayList, LinkedListSequencedCollection
  • LinkedHashSet, TreeSetSequencedSet
  • LinkedHashMap, TreeMapSequencedMap

This means that if you already use these collections, you automatically get the new capabilities!

2. Core methods of SequencedCollection, SequencedSet, SequencedMap

Methods of SequencedCollection

E getFirst();      // Get the first element
E getLast();       // Get the last element
SequencedCollection<E> reversed(); // Get the collection in reverse order

Methods of SequencedSet

The same methods as in SequencedCollection, plus everything that Set does.

Methods of SequencedMap

Map.Entry<K, V> firstEntry();    // First entry (key–value)
Map.Entry<K, V> lastEntry();     // Last entry (key–value)
SequencedMap<K, V> reversed();   // Map in reverse order

3. Examples of using the new interfaces

Example 1: Getting the first and last element

import java.util.*;

public class SequencedDemo {
    public static void main(String[] args) {
        SequencedCollection<String> sc = new ArrayList<>();
        sc.add("Java");
        sc.add("Python");
        sc.add("Kotlin");

        // Get the first and last element
        String first = sc.getFirst(); // "Java"
        String last = sc.getLast();   // "Kotlin"

        System.out.println("First: " + first);
        System.out.println("Last: " + last);
    }
}

Output:

First: Java
Last: Kotlin

Example 2: Reversing a collection

SequencedCollection<String> sc = new LinkedList<>();
sc.add("A");
sc.add("B");
sc.add("C");

SequencedCollection<String> reversed = sc.reversed();
System.out.println(reversed); // [C, B, A]

Note: reversed() returns a view of the collection in reverse order. If you change the original collection, the reversed view will change as well!

Example 3: Working with SequencedSet

SequencedSet<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(200);
set.add(300);

System.out.println("First element: " + set.getFirst()); // 100
System.out.println("Last element: " + set.getLast()); // 300

SequencedSet<Integer> reversedSet = set.reversed();
System.out.println(reversedSet); // [300, 200, 100]

Example 4: Working with SequencedMap

SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.put("apple", 5);
map.put("banana", 3);
map.put("cherry", 7);

Map.Entry<String, Integer> first = map.firstEntry();
Map.Entry<String, Integer> last = map.lastEntry();

System.out.println("First: " + first.getKey() + " = " + first.getValue()); // apple = 5
System.out.println("Last: " + last.getKey() + " = " + last.getValue()); // cherry = 7

SequencedMap<String, Integer> reversedMap = map.reversed();
System.out.println(reversedMap); // {cherry=7, banana=3, apple=5}

4. How does this relate to your application?

Suppose your learning app stores a list of users who have logged in, and you want to quickly get the first and the last user (for example, to show “who logged in first” and “who last”). Previously, you had to write something like:

List<String> users = new ArrayList<>();
// ... add users
String first = users.get(0);
String last = users.get(users.size() - 1);

But if the collection is not a list, and, say, a LinkedHashSet (where elements are unique and order is preserved), that trick no longer works:

Set<String> users = new LinkedHashSet<>();
// ... add users
// How to get the first? Only via an iterator:
String first = users.iterator().next();
// And the last one? Only by iterating over all elements!

Now it’s simpler and more universal:

SequencedSet<String> users = new LinkedHashSet<>();
// ... add users
String first = users.getFirst();
String last = users.getLast();

This not only reduces the amount of code, but also makes it more readable and safer.

5. Diagram of the new interfaces

classDiagram
    Collection <|-- SequencedCollection
    List <|-- SequencedCollection
    Set <|-- SequencedSet
    Map <|-- SequencedMap
    SequencedCollection <|-- SequencedSet
    SequencedSet <|-- LinkedHashSet
    SequencedSet <|-- TreeSet
    SequencedCollection <|-- ArrayList
    SequencedCollection <|-- LinkedList
    SequencedMap <|-- LinkedHashMap
    SequencedMap <|-- TreeMap

6. Useful details

Practical benefits of SequencedCollection

  • A single interface for working with order: You no longer have to remember where get(0) works, where you need an iterator, and where you cannot get the first element at all.
  • Convenient for queues and stacks: Easily get the first (head) and last (tail) element.
  • Safety and readability: Fewer errors related to incorrect collection usage; the code becomes self-documenting.
  • Fast collection reversing: The reversed() method lets you easily get the reverse order without manual manipulation.
  • Ease of maintenance and evolution: If in the future you want to replace, for example, ArrayList with LinkedHashSet, code that uses SequencedCollection won’t need to be rewritten.

Implementation details

  • Not all collections implement SequencedCollection: For example, HashSet and HashMap do not guarantee order, so they do not implement the new interfaces.
  • Methods may throw exceptions: If a collection is empty, calling getFirst() or getLast() will result in a NoSuchElementException. Don’t forget to check that the collection isn’t empty!
  • reversed() is a view, not a copy: Changes to the original collection are reflected in the reversed view and vice versa.
  • Compatibility: The new interfaces are available starting with Java 21. If you’re using an older Java version, these capabilities aren’t available yet (but it’s a great reason to upgrade!).
  • Generics: All the new interfaces fully support generics, so you can work with any data types.

7. Common mistakes when working with SequencedCollection

Error No. 1: Expecting order support from collections that don’t guarantee it. If you try to cast a HashSet to a SequencedSet, you’ll get a compilation error — HashSet has no order and does not implement this interface.

Error No. 2: Ignoring empty collections. Calling getFirst() or getLast() on an empty collection will throw an exception. Before calling these methods, check that the collection isn’t empty:

if (!sc.isEmpty()) {
    String first = sc.getFirst();
}

Error No. 3: Gotchas with reversed(). The reversed() method returns a view, not a copy. If you modify the reversed view, the original collection will change (and vice versa). This can lead to surprises if you don’t expect such behavior.

Error No. 4: Using the new interfaces on older Java versions. If your project is compiled with a version below Java 21, the compiler won’t find these interfaces. Check the JDK version in your project settings!

1
Task
JAVA 25 SELF, level 34, lesson 4
Locked
Smart task dispatcher: check for emptiness before working 🤖
Smart task dispatcher: check for emptiness before working 🤖
1
Task
JAVA 25 SELF, level 34, lesson 4
Locked
Algorithm of steps: forward and reverse control 🔄
Algorithm of steps: forward and reverse control 🔄
1
Survey/quiz
Modern Collections, level 34, lesson 4
Unavailable
Modern Collections
Modern collections and immutability
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION