This tutorial shows the usage examples of SequencedMap
in Java.
Map
is a data type that's been supported in the Java programming language since a long time ago. In Java 21, there is a new interface called SequencedMap
. It defines a Map
that has a well-defined encounter order, supports operations at both ends, and is reversible. There are several methods defined in the interface that simplify how to access and add entries to the map. In this tutorial, I am going to show you what you can do with the new interface.
Create SequencedMap
Creating a SequencedMap
can be done by creating a LinkedHashMap
since it implements the interface. Therefore, an instance of LinkedHashMap
can access the methods of SequencedMap
. Other implementations of Map
such as HashMap
and TreeMap
do not implement the interface.
SequencedMap<String, Integer> myMap = new LinkedHashMap<>();
myMap.put("one", 1);
myMap.put("two", 2);
myMap.put("three", 3);
System.out.println(myMap);
SequencedMap<String, Integer> emptyMap = new LinkedHashMap<>();
System.out.println(emptyMap);
Output:
{one=1, two=2, three=3}
{}
Get First Entry
The first entry of the map can be obtained by using the firstEntry
method. If the map is empty, it will return null
.
Map.Entry<String, Integer> firstEntry = myMap.firstEntry();
System.out.println(firstEntry);
Map.Entry<String, Integer> firstEntryEmpty = emptyMap.firstEntry();
System.out.println(firstEntryEmpty);
Output:
one=1
null
Get Last Entry
To get the last entry of the map, use the lastEntry
method. If the map is empty, it will return null
.
Map.Entry<String, Integer> lastEntry = myMap.lastEntry();
System.out.println(lastEntry);
Map.Entry<String, Integer> lastEntryEmpty = emptyMap.lastEntry();
System.out.println(lastEntryEmpty);
Output:
three=3
null
Add First Entry
The putFirst
method can be used to put an entry as the first one. If there's an existing entry with the same key, it will be replaced and the entry will be set as the first one after the operation completes.
myMap.putFirst("zero", 0);
System.out.println(myMap);
myMap.putFirst("one", -1);
System.out.println(myMap);
Output:
{zero=0, one=1, two=2, three=3}
{one=-1, zero=0, two=2, three=3}
Add Last Entry
The putLast
method can be used to put an entry as the last one. If there's an existing entry with the same key, it will be replaced and the entry will be set as the last one after the operation completes.
myMap.putLast("four", 4);
System.out.println(myMap);
myMap.putLast("three", -3);
System.out.println(myMap);
Output:
{one=-1, zero=0, two=2, three=3, four=4}
{one=-1, zero=0, two=2, four=4, three=-3}
Poll First Entry
To get and remove the first entry, you can use the pollFirstEntry
method. If the map is empty, it will return null
Map.Entry<String, Integer> polledFirstEntry = myMap.pollFirstEntry();
System.out.println(polledFirstEntry);
System.out.println(myMap);
Map.Entry<String, Integer> polledFirstEntryEmpty = emptyMap.pollFirstEntry();
System.out.println(polledFirstEntryEmpty);
Output:
one=-1
{zero=0, two=2, four=4, three=-3}
null
Poll Last Entry
To get and remove the last entry, you can use the pollLastEntry
method. If the map is empty, it will return null
Map.Entry<String, Integer> polledLastEntry = myMap.pollLastEntry();
System.out.println(polledLastEntry);
System.out.println(myMap);
Map.Entry<String, Integer> polledLastEntryEmpty = emptyMap.pollLastEntry();
System.out.println(polledLastEntryEmpty);
Output:
three=-3
{zero=0, two=2, four=4}
null
Reverse Entries
The order of the entries can be reversed by using the reversed
method. The method returns the reversed view of the collection.
SequencedMap<String, Integer> reversedMap = myMap.reversed();
System.out.println(myMap);
System.out.println(reversedMap);
Output:
{zero=0, two=2, four=4}
{four=4, two=2, zero=0}
Actually the returned map still refers to the same object as the original one. The reversed
method only returns the reversed view. Therefore, if you try to add or remove an entry of the original map, it will affect the entries of the reversed one. The same also applies for the opposite.
myMap.putFirst("x", 100);
System.out.println(myMap);
System.out.println(reversedMap);
myMap.putFirst("y", 200);
System.out.println(myMap);
System.out.println(reversedMap);
Output:
{x=100, zero=0, two=2, four=4}
{four=4, two=2, zero=0, x=100}
{x=100, zero=0, two=2, four=4, y=200}
{y=200, four=4, two=2, zero=0, x=100}
Object Comparison
If you need to perform object comparison, you need to know that even a SequencedMap
has ordered elements, the implementation of the equals
and hashCode
methods are the same as Map.equals
and Map.hashCode
. So, if you have two SequencedMap
s with the same entries but different orders, comparing those two using equals
will return true
.
boolean isEqual = myMap.equals(reversedMap);
System.out.println(isEqual);
System.out.println(myMap.hashCode());
System.out.println(reversedMap.hashCode());
System.out.println(myMap.hashCode() == reversedMap.hashCode());
Output:
true
6999781
6999781
true
Full Code
package com.woolha.example.sequencedcollection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SequencedMap;
public class SequencedMapExample {
public static void main(String[] args) {
SequencedMap<String, Integer> myMap = new LinkedHashMap<>();
myMap.put("one", 1);
myMap.put("two", 2);
myMap.put("three", 3);
System.out.println(myMap); // {one=1, two=2, three=3}
SequencedMap<String, Integer> emptyMap = new LinkedHashMap<>();
System.out.println(emptyMap); // {}
Map.Entry<String, Integer> firstEntry = myMap.firstEntry();
System.out.println(firstEntry); // one=1
Map.Entry<String, Integer> firstEntryEmpty = emptyMap.firstEntry();
System.out.println(firstEntryEmpty); // null
Map.Entry<String, Integer> lastEntry = myMap.lastEntry();
System.out.println(lastEntry); // three=3
Map.Entry<String, Integer> lastEntryEmpty = emptyMap.lastEntry();
System.out.println(lastEntryEmpty); // null
myMap.putFirst("zero", 0);
System.out.println(myMap); // {zero=0, one=1, two=2, three=3}
myMap.putFirst("one", -1);
System.out.println(myMap); // {one=-1, zero=0, two=2, three=3}
myMap.putLast("four", 4);
System.out.println(myMap); // {one=-1, zero=0, two=2, three=3, four=4}
myMap.putLast("three", -3);
System.out.println(myMap); // {one=-1, zero=0, two=2, four=4, three=-3}
Map.Entry<String, Integer> polledFirstEntry = myMap.pollFirstEntry();
System.out.println(polledFirstEntry); // one=-1
System.out.println(myMap); // {zero=0, two=2, four=4, three=-3}
Map.Entry<String, Integer> polledFirstEntryEmpty = emptyMap.pollFirstEntry();
System.out.println(polledFirstEntryEmpty); // null
Map.Entry<String, Integer> polledLastEntry = myMap.pollLastEntry();
System.out.println(polledLastEntry); // three=-3
System.out.println(myMap); // {zero=0, two=2, four=4}
Map.Entry<String, Integer> polledLastEntryEmpty = emptyMap.pollLastEntry();
System.out.println(polledLastEntryEmpty); // null
SequencedMap<String, Integer> reversedMap = myMap.reversed();
System.out.println(myMap); // {zero=0, two=2, four=4}
System.out.println(reversedMap); // {four=4, two=2, zero=0}
myMap.putFirst("x", 100);
System.out.println(myMap); // {x=100, zero=0, two=2, four=4}
System.out.println(reversedMap); // {four=4, two=2, zero=0, x=100}
reversedMap.putFirst("y", 200);
System.out.println(myMap); // {x=100, zero=0, two=2, four=4, y=200}
System.out.println(reversedMap); // {y=200, four=4, two=2, zero=0, x=100}
boolean isEqual = myMap.equals(reversedMap);
System.out.println(isEqual); // true
System.out.println(myMap.hashCode()); // 6999781
System.out.println(reversedMap.hashCode()); // 6999781
System.out.println(myMap.hashCode() == reversedMap.hashCode()); // true
}
}
Summary
The SequencedMap
interface defines some methods that could be useful for a map with ordered elements. Therefore, it becomes more practical to perform common operations such as getting or retrieving an entry at the first or last index. The built-in implementation of Map
that uses the interface is LinkedHashMap
.
You can also read about: