Exploring SequencedList, Sequenced Sets, and SequencedMap in Java 21

Java Development Kit (JDK) 21, which is scheduled to be released in September as the next long-term support version, follows JDK 17 LTS, the latest long-term support release.

In Java, a sequenced collection is a type of collection where the elements are arranged in a specific order that is maintained throughout. This order allows us to traverse the collection both forward and backward.

List

Starting from Java 21, the List<E> interface extends the SequencedCollection<E> interface. By looking into the SequencedCollection interface, we can find helpful methods such as:


List<String> list = new ArrayList<>();
list.add("Element 1");
list.add("Element 2");
list.add("Element 3");
System.out.println("Before adding: " + list);

// Add the first element
list.addFirst("New Element");

// Add the last element
list.addLast("Last Element");

System.out.println("First element: " + list.getFirst());
System.out.println("Last element: " + list.getLast());

// Remove First Element
list.removeFirst();

// Remove Last element
list.removeLast();
System.out.println("After removing first and last element: " + list);

// Reverse
System.out.println("Reverse: " + list.reversed());
    

Output


Before adding: [Element 1, Element 2, Element 3]
First element: New Element
Last element: Last Element
After removing first and last element: [Element 1, Element 2, Element 3]
Reverse: [Element 3, Element 2, Element 1]
    

Sequenced Sets

A sequenced set is a special type of set in Java that maintains a specific order of elements. It is a part of the SequencedCollection family of collections. What makes a sequenced set unique is that it does not allow duplicate elements.

Unlike regular sets, which do not have a defined order, sequenced sets preserve the order in which elements are inserted. This means that the elements in a sequenced set can be accessed in a predictable manner.

Sorted Set:

SortedSet extends Set, SequencedSet


SortedSet<Integer> sortedSet = new TreeSet<>();
sortedSet.add(3);
sortedSet.add(1);
sortedSet.add(5);
System.out.println("Sorted Set: " + sortedSet);
    

Output


Sorted Set: [1, 3, 5]
    

As you can see, the elements are automatically sorted in ascending order when added to the SortedSet.

Now, what if we attempt to add a firstElement or lastElement using SequencedCollections?


sortedSet.addFirst(6);
    

Output


UnsupportedOperationException
    

Even though SortedSet extends SequencedSet and the elements are automatically sorted in ascending order, the addFirst and addLast operations throw UnsupportedOperationException.

Reverse:

To reverse the order of elements in the SortedSet, we can use the reversed() method. This method returns a view of the SortedSet with the elements in reverse order. Let's see an example:


System.out.println("Sorted Set reverse: " + sortedSet.reversed());
    

Output


Sorted Set reverse: [5, 3, 1]
    

Remove firstElement and lastElement:

To remove the firstElement and lastElement from the SortedSet, we can use the removeFirst() and removeLast() methods, respectively. These methods remove the respective elements from the set and return the removed element. Let's take a look at an example:


System.out.println("Sorted Set remove firstElement: " + sortedSet.removeFirst());
System.out.println("Sorted Set remove lastElement: " + sortedSet.removeLast());
System.out.println("Sorted Set: " + sortedSet);
    

Output


Sorted Set remove firstElement: 1
Sorted Set remove lastElement: 5
Sorted Set: [3]
    

LinkedHashSet:

LinkedHashSet is another implementation of the Set interface in Java. It not only extends the HashSet class but also implements the SequencedSet interface, making it a part of the SequencedCollection family.

Examples using LinkedHashSet:

Let's take a look at some examples using LinkedHashSet:


LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();

// Add elements to the set
linkedHashSet.add("Element 1");
linkedHashSet.add("Element 2");
linkedHashSet.add("Element 3");

System.out.println("LinkedHashSet: " + linkedHashSet);
System.out.println("LinkedHashSet reverse: " + linkedHashSet.reversed());

linkedHashSet.addFirst("Element 4");
System.out.println("LinkedHashSet: " + linkedHashSet);

linkedHashSet.removeFirst();
System.out.println("LinkedHashSet after removeFirst: " + linkedHashSet);

linkedHashSet.removeLast();
System.out.println("LinkedHashSet after removeLast: " + linkedHashSet);
    

Output


LinkedHashSet: [Element 1, Element 2, Element 3]
LinkedHashSet reverse: [Element 3, Element 2, Element 1]
LinkedHashSet: [Element 4, Element 1, Element 2, Element 3]
LinkedHashSet after removeFirst: [Element 1, Element 2, Element 3]
LinkedHashSet after removeLast: [Element 1, Element 2]
    

In the given code example, we create a LinkedHashSet and add elements to it. The order of insertion is maintained in the set, so the elements are displayed in the same order as they were added. The reversed() method allows us to obtain a reversed view of the LinkedHashSet, providing the elements in reverse order.

Using the addFirst() method, we can insert an element at the beginning of the LinkedHashSet. In the example, "Element 4" is added to the set at the first position.

The removeFirst() method removes and returns the first element from the LinkedHashSet. In our example, the first element "Element 4" is removed.

Similarly, the removeLast() method removes and returns the last element from the LinkedHashSet. In our example, the last element "Element 3" is removed.

As you can see, LinkedHashSet provides convenient methods to add, remove, and retrieve elements while maintaining the order of insertion. It offers a combination of set functionality and sequence preservation.

SequencedMap

A SequencedMap is a special type of Map that maintains a specific order for its mappings. It ensures that the mappings are arranged in a particular order, preserving the order in which the mappings were added.

Some methods supported in SequencedMap include:

These methods provide convenient ways to manipulate and retrieve key-value mappings in a SequencedMap while maintaining their order. They offer additional functionality beyond the standard Map interface, enhancing the capability of working with ordered mappings.

// Create a new instance of LinkedHashMap
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();

// Add key-value pairs to the map
linkedHashMap.put("Apple", 10);
linkedHashMap.put("Banana", 20);
linkedHashMap.put("Orange", 30);
linkedHashMap.put("Mango", 40);

// Display the contents of the LinkedHashMap
System.out.println("LinkedHashMap: " + linkedHashMap);
// Reverse
System.out.println("LinkedHashMap reverse: " + linkedHashMap.reversed());

// FirstEntry
System.out.println("LinkedHashMap firstEntry: " + linkedHashMap.firstEntry());

// LastEntry
System.out.println("LinkedHashMap lastEntry: " + linkedHashMap.lastEntry());

// PollFirstEntry
System.out.println("LinkedHashMap pollFirstEntry: " + linkedHashMap.pollFirstEntry());
System.out.println("LinkedHashMap: " + linkedHashMap);

// PollLastEntry
System.out.println("LinkedHashMap pollLastEntry: " + linkedHashMap.pollLastEntry());
System.out.println("LinkedHashMap: " + linkedHashMap);

// PutFirst
linkedHashMap.putFirst("Apple", 10);
System.out.println("LinkedHashMap after putFirst: " + linkedHashMap);

// PutLast
linkedHashMap.putLast("Mango", 40);
System.out.println("LinkedHashMap after putLast: " + linkedHashMap);

// SequencedKeySet
System.out.println("LinkedHashMap sequencedKeySet: " + linkedHashMap.sequencedKeySet());

// SequencedValues
System.out.println("LinkedHashMap sequencedValues: " + linkedHashMap.sequencedValues());

// SequencedEntrySet
System.out.println("LinkedHashMap sequencedEntrySet: " + linkedHashMap.sequencedEntrySet());

Output:

LinkedHashMap: {Apple=10, Banana=20, Orange=30, Mango=40}
LinkedHashMap reverse: {Mango=40, Orange=30, Banana=20, Apple=10}
LinkedHashMap firstEntry: Apple=10
LinkedHashMap lastEntry: Mango=40
LinkedHashMap pollFirstEntry: Apple=10
LinkedHashMap: {Banana=20, Orange=30, Mango=40}
LinkedHashMap pollLastEntry: Mango=40
LinkedHashMap: {Banana=20, Orange=30}
LinkedHashMap after putFirst: {Apple=10, Banana=20, Orange=30}
LinkedHashMap after putLast: {Apple=10, Banana=20, Orange=30, Mango=40}
LinkedHashMap sequencedKeySet: [Apple, Banana, Orange, Mango]
LinkedHashMap sequencedValues: [10, 20, 30, 40]
LinkedHashMap sequencedEntrySet: [Apple=10, Banana=20, Orange=30, Mango=40]

SortedMap

A SortedMap in Java is a map that maintains its keys in sorted order. The keys in a SortedMap are arranged in a specific order, allowing for efficient retrieval, addition, and removal of elements based on their keys.

SortedMap extends SequencedMap, which provides the map with a well-defined encounter order.

In a SortedMap, the keys are ordered based on their natural ordering or a custom Comparator provided during the creation of the SortedMap. The ordering is determined by the keys themselves and not by the order of insertion. This means that adding elements using putFirst or putLast will result in an UnsupportedOperationException, as the order is automatically determined by the keys.

All other operations in a SortedMap related to SequencedMap are similar to those in a LinkedHashMap.