Java - Using SequencedMap Examples

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 SequencedMaps 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: