Java 8 map sort by value, key or insert order

Since Java 8 sorting of HashMap in Java it's much easier by using streams and lambdas. In this post we will see:

  • Java map sort by key ascending
  • Java map sort by key descending
  • Java map sort by value ascending
  • Java map sort by value descending
  • Java map get insert order

Using some advantages from functional programming, Stream API and lambda expressions is a game changer for Java world.

Lets have a simple map containing African countries with capitals:

Key, Value
Zimbabwe, Harare
Angola, Luanda
Cameroon, Yaounde
Sudan, Khartoum
Niger, Niamey

You can be interested also in :

Java map examples

Java map sort by key ascending

The easiest way to convert a HashMap in Java is by using TreeMap:

SortedMap<String, String> treeMap = new TreeMap<>(unsortMap);

example which sorts a map by keys in ascending order. This example is working even before Java 8.

Map<String, String> keyAscMap = new HashMap<>();
initMap(keyAscMap);
System.out.println("Before");
printMap(keyAscMap);

SortedMap<String, String> treeMap = new TreeMap<>(keyAscMap);

System.out.println("After");
printMap(treeMap);

//init a map
public static void initMap(Map<String, String> map) {
    map.put("Zimbabwe", "Harare");
    map.put("Angola", "Luanda");
    map.put("Cameroon", "Yaounde");
    map.put("Sudan", "Khartoum");
    map.put("Niger", "Niamey");
}

//print a map
public static <K, V> void printMap(Map<K, V> map) {
    map.forEach((key, value) -> System.out.printf("%s %s%n", key, value));
    System.out.println();
}

result:

Before
Cameroon Yaounde
Angola Luanda
Niger Niamey
Sudan Khartoum
Zimbabwe Harare

After
Angola Luanda
Cameroon Yaounde
Niger Niamey
Sudan Khartoum
Zimbabwe Harare

Java map sort by key ascending

Sorting a map in descending order can be done in Java 8 with Comparator and compareTo:

Map<String, String> sortedMap = new TreeMap<>(
        (Comparator<String>) (o1, o2) -> o1.compareTo(o2)
);

full example

Map<String, String> keyDescMap = new HashMap<>();
initMap(keyDescMap); // you can get the init method from the first section

System.out.println("Before");
printMap(keyDescMap);

Map<String, String> keyDescSortMap = new TreeMap<>(
        (Comparator<String>) (o1, o2) -> o2.compareTo(o1)
);
keyDescSortMap.putAll(keyDescMap);

System.out.println("After");
printMap(keyDescSortMap);

result:

Before
Cameroon Yaounde
Angola Luanda
Niger Niamey
Sudan Khartoum
Zimbabwe Harare

After
Zimbabwe Harare
Sudan Khartoum
Niger Niamey
Cameroon Yaounde
Angola Luanda

Java map sort by value ascending

In Java 8 sorting a Map / HashMap ( Map is an interface while HashMap is a class implementation of this interface) can be done with method sorted() of Stream class and Comparator. Sorting by values can be done by method comparingByValue() of the Entry class. Newly added method since Java 8 makes sorting easier.

Sorting HashMap by value in Java 8 using streams, sorted() and LinkedHashMap:

Map<String, String> valueAscSortMap = valueAscMap.entrySet().stream()
        .sorted(Map.Entry.<String, String> comparingByValue())
        .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
HashMap<String, String> valueAscMap = new HashMap<>();
initMap(valueAscMap); // you can get the init method from the first section
System.out.println("Before");
printMap(valueAscMap);

Map<String, String> valueAscSortMap = valueAscMap.entrySet().stream()
        .sorted(Map.Entry.<String, String> comparingByValue())
        .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
        
System.out.println("After");
printMap(valueAscSortMap);

result:

Before
Cameroon Yaounde
Angola Luanda
Niger Niamey
Sudan Khartoum
Zimbabwe Harare

After
Zimbabwe Harare
Sudan Khartoum
Angola Luanda
Niger Niamey
Cameroon Yaounde

Java map sort by value descending

The reverse sorting by value (in descending order) is possible by :

.sorted(Map.Entry.<String, String> comparingByValue().reversed()

full example:

HashMap<String, String> valueDescMap = new HashMap<>();
initMap(valueDescMap); // you can get the init method from the first section
System.out.println("Before");
printMap(valueDescMap);

Map<String, String> valueDescSortMap = valueDescMap.entrySet().stream()
        .sorted(Map.Entry.<String, String> comparingByValue().reversed())
        .collect(
                toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1,
                        LinkedHashMap::new));
                        
System.out.println("After");
printMap(valueDescSortMap);

result:

Before
Cameroon Yaounde
Angola Luanda
Niger Niamey
Sudan Khartoum
Zimbabwe Harare

After
Cameroon Yaounde
Niger Niamey
Angola Luanda
Sudan Khartoum
Zimbabwe Harare

Java map get insert order

If the insert order is important for you then you need to use LinkedHashMap. This will ensure that insert order is preserved and you can access the elements in the same way in which you inserted them. Here you can see another way of printing a map in Java:

Map<String, String> orderedMap = new LinkedHashMap<>();
initMap(orderedMap);

System.out.println("Keep Order");

for (Map.Entry<String,String> item : orderedMap.entrySet()){
    System.out.println(item.getKey() + item.getValue());
}

result:

Order
ZimbabweHarare
AngolaLuanda
CameroonYaounde
SudanKhartoum
NigerNiamey

Note: that in the other cases the insert order is lost!

Related Article