Sort a HashMap by Key in Java

  1. Sort the Keyset Using the TreeMap Class in Java
  2. Sorting the Keyset Using the Java8 Functions
  3. Understand the Map Initialization Stream Function in Java
  4. Understand the Map Transformation Stream Function in Java

The term HashMap in Java language is the collection derived from the Map interface. This collection or class is present in the java.util package and stores the data in key-value pair. Note that there cannot be two keys on the map. If the duplicate key gets inserted, then the value of the respective key gets replaced by the newer value.

Sort the Keyset Using the TreeMap Class in Java

Below is the code block to demonstrate the sorting of a HashMap by its key.

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class HashMapSortByKey {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("2", "Value5");
        map.put("3", "Value1");
        map.put("1", "Value2");
        map.put("4", "Value3");
        map.put("9", "Value4");
        map.put("hi11", "Value6");
        map.put("hi0", "Value7");
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        System.out.println();
        System.out.print("Ordered List: ");
        TreeMap<String, String> map1 = new TreeMap<>(map);
        for (String s : map1.keySet()) {
            System.out.print(" " + s);
        }
    }
}

In the code block above, the map object is declared using the default constructor of HashMap with the new keyword. The statement creates an instance of the HashSet class and assigns the value to the Map interface reference. The types are compatible as the HashMap class implements the Map interface internally.

The map gets initialized with some set of key values. The insertion happens using the put method that binds the key to its specified value. The method returns the previous value if the key was already present in the map and overrides the previous value with a specified one. The function returns a null value when the key is not already present in the map. It throws IllegalArgumentException if the property of the key or value prohibits the value from insertion.

Now for iterating over the map, the for-each loop gets used. The map.keySet function returns the Set format of all the keys in the map. The keyset function gets a collection in the for-each loop over which the variable can iterate; hence, printing the keys. It will print the values in an unordered format, and there’s no well-defined manner in which the user will get the output.

To sort the map keys, the TreeSet class gets used. The map variable is given as a constructor parameter in the TreeSet constructor at the time of instantiation. The class implements the Comparable interface to sort the keys. When the resultant map, map1, gets printed, it prints the sorted keys in the output.

Below is the output of the code block above.

Output:

Unordered List:  1 hi11 2 3 4 9 hi0
Ordered List:  1 2 3 4 9 hi0 hi11

Sorting the Keyset Using the Java8 Functions

Java8 provides a privilege of functional programming, which helps in working over the chain functions. In the program below, it is seen that instantiation and initialization happen in a statement. Whereas in the first example code, it is a tedious task to populate the map. Understanding the Streams and functions to instantiate the map in a single statement is given below.

Streams is an interface in the java.util package that provides flexibility to work over the sequence of operations in a single go. The Streams works in the pipeline where an emitter emits the data; it gets filtered, processed, transformed, and much more as per the users’ need.

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Stream;

import static java.util.AbstractMap.SimpleEntry;
import static java.util.stream.Collectors.toMap;

public class HashMapSortByKey {
    public static void main(String[] args) {
         Map<String, String> map = Stream.of(new SimpleEntry<>("key6", "value1"),
                new SimpleEntry<>("key12", "value2"),
                new SimpleEntry<>("key9", "value3"))
                .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
        
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        Map<String, String> mapSortedByKey = map
                .entrySet()
                .stream()
                .sorted(Map.Entry.<String, String>comparingByKey().reversed())
                .collect(Collectors.toMap(Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newValue) -> oldValue,
                        LinkedHashMap::new));

        System.out.println();
        System.out.print("Ordered List: ");
        for (String s1 : mapSortedByKey.keySet()) {
            System.out.print(" " + s1);
        }
    }
}

Understand the Map Initialization Stream Function in Java

Firstly, the Stream calls the of() function that returns the specified stream in sequential order. The function creates objects of the SimpleEntry class to create mappings of the key-value form. The class implements the Entry interface and has the entrySet method that returns the collection view of the map.

Once the key-value entries get formed, the values are collected to a map using the collect function. It is a terminal function meaning no more methods can get invoked after the collect function. The function packages or binds the stream values in the desired data structures.

The input given as a parameter is always a Collector reference. The toMap is a static function in the Collectors class that returns a Collector that binds the stream elements in a Map. The function takes a key Mapper and key Value Function as its parameter. Now, the method reference :: operator means calling the functions of the specified class.

In the key Mapper, the getKey function extracts the key from the populated EntrySet stream. Similarly, in the key Value function, the getValue function gets called to get the value from the EntrySet stream.

The Collector Function variables from the code above are the functional interfaces in Java that have a single abstract method for the functionality. The abstract method’s definitions get defined in classes that implement them.

Understand the Map Transformation Stream Function in Java

Over the map instance that just formed, the entrySet function gets invoked. The function returns the set view of the map entries and is present in the Map interface. Over these entries, the stream method is called to convert the entries in the sequential stream. Over the stream of entries, the sorted function gets invoked.

It takes a Comparator to compare the Stream elements. The sorted function finally returns the sorted stream of the given entries. The comparingByKey function returns the Map.Entry comparator with the default ordering on the key. The comparator returns a key set; if a key found is null, it throws NullPointerException from the function.

When the entry set is retrieved, the reversed function gets called to reverse the elements’ order in the collection. Finally, the collect function gets invoked over the map stream. The function is a terminal operator, and hence, no operations can get called after the collect function. Into the function, the toMap function gets called to transform the stream into the map.

The function takes four parameters: the keyMapper is a function that produces keys, the valueMapper is a mapping function that creates its values, the mergeFunction is a BinaryOperator that merges a function, and the mapSupplier is a Supplier function which returns a new, empty Map where the results get inserted. Finally, the resultant console output gets printed above.

Output:

Unordered List:  key12 key6 key9
Ordered List:  key9 key6 key12
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - Java HashMap

  • Iterate Through HashMap in Java