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 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!