Sequenced Collections in Java

Naveen AnamaneniUpdated · 4 min read

Sequenced collections, added in Java 21, are three new interfaces for collections whose elements have a defined order: SequencedCollection, SequencedSet and SequencedMap. They give every ordered collection the same methods to read, add and remove the first and last elements, and to get a reversed view. Before Java 21, each class had its own way to do this: list.get(list.size() - 1) for a list, deque.getLast() for a deque, and a full loop for a LinkedHashSet. In this lesson, you will learn the new interfaces and their methods.

The Three Interfaces

InterfaceExtendsImplemented by
SequencedCollection<E>Collection<E>List, Deque and their classes
SequencedSet<E>SequencedCollection<E>, Set<E>LinkedHashSet, SortedSet (TreeSet)
SequencedMap<K, V>Map<K, V>LinkedHashMap, SortedMap (TreeMap)

HashSet and HashMap are not sequenced, because they have no defined order.

Every ordered collection now shares first, last and reversed methods

Methods of SequencedCollection

MethodDescription
E getFirst()It returns the first element.
E getLast()It returns the last element.
void addFirst(E e)It adds an element at the front.
void addLast(E e)It adds an element at the end.
E removeFirst()It removes and returns the first element.
E removeLast()It removes and returns the last element.
SequencedCollection<E> reversed()It returns a reversed view.

SequencedMap has the matching methods firstEntry, lastEntry, pollFirstEntry, pollLastEntry, putFirst, putLast and reversed, plus sequencedKeySet, sequencedValues and sequencedEntrySet.

Example: The Same Methods on Different Classes

Let's see an example that calls the same methods on a list, a deque and a set.

Sequenced.java▶ Try it
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.SequencedCollection;
 
public class Sequenced {
    static void show(SequencedCollection<String> c) {
        System.out.println(c.getClass().getSimpleName() + ": first "
            + c.getFirst() + ", last " + c.getLast()
            + ", reversed " + c.reversed());
    }
 
    public static void main(String[] args) {
        List<String> names = List.of("Navika", "Srihitha", "Advitha");
        show(new ArrayList<>(names));
        show(new ArrayDeque<>(names));
        show(new LinkedHashSet<>(names));
    }
}
Output
ArrayList: first Navika, last Advitha, reversed [Advitha, Srihitha, Navika]
ArrayDeque: first Navika, last Advitha, reversed [Advitha, Srihitha, Navika]
LinkedHashSet: first Navika, last Advitha, reversed [Advitha, Srihitha, Navika]

Explanation: One method, show, works with three very different classes because they all implement SequencedCollection. Before Java 21, getting the last element of a LinkedHashSet needed a loop over every element.

Example: SequencedMap

SeqMap.java▶ Try it
import java.util.LinkedHashMap;
import java.util.SequencedMap;
 
public class SeqMap {
    public static void main(String[] args) {
        SequencedMap<String, Integer> marks = new LinkedHashMap<>();
        marks.put("Navika", 91);
        marks.put("Srihitha", 78);
        marks.put("Advitha", 85);
 
        System.out.println("First: " + marks.firstEntry());
        System.out.println("Last: " + marks.lastEntry());
 
        marks.putFirst("Anamaneni", 66);
        System.out.println(marks);
        System.out.println("Reversed: " + marks.reversed());
        System.out.println("Polled: " + marks.pollLastEntry());
        System.out.println(marks);
    }
}
Output
First: Navika=91
Last: Advitha=85
{Anamaneni=66, Navika=91, Srihitha=78, Advitha=85}
Reversed: {Advitha=85, Srihitha=78, Navika=91, Anamaneni=66}
Polled: Advitha=85
{Anamaneni=66, Navika=91, Srihitha=78}

Explanation: firstEntry and lastEntry read the ends. putFirst inserts a pair at the front, which a LinkedHashMap couldn't do before Java 21. reversed returns a reversed view, and pollLastEntry removes the last pair.

Common Mistakes

Calling getFirst on an empty collection. It throws NoSuchElementException.

Calling addFirst on a List.of(...) list. It's unmodifiable and throws UnsupportedOperationException.

Calling addFirst on a TreeSet. Sorted collections decide positions themselves, so it throws UnsupportedOperationException.

Practice

  1. Easy: Create a LinkedHashSet of five cities and print the first and last city, then the set in reverse.
  2. Harder: Write one generic method swapEnds(SequencedCollection<T> c) that removes the first and last elements and adds them back at the opposite ends. Test it on an ArrayList and an ArrayDeque.

Quick check: Sequenced collections

4 questions
1In which Java version were sequenced collections added?
2Which class is NOT a SequencedCollection?
3What does reversed() return?
4Which method adds a pair at the front of a LinkedHashMap?

Key Takeaways

Was this tutorial helpful?

Lesson 298 of 482