In this article, we will discuss different ways to sort a Map entries (key-value pairs) by its Value
Before proceeding with this sorting examples understand below items,
- What is Map ?
- What is Map.Entry ?
- HashMap and its properties
- How to iterate Map ?
- Sorting Map by its Key – before Java 8
- Sorting Map by its Value – before Java 8
Different approaches of Sorting a Map by its Value :
- TreeMap class
- ArrayList class and Collections.sort() method
- TreeSet class
- Java 8 – Lambda function
- Java 8 – Stream sorted() method
- Java 8 – Map.Entry.comparingByValue() comparator
1. Using TreeMap class
- Ascending-order values :- Create TreeMap object and pass Comparator as constructor-argument by providing/implementing/overriding code/logic for ascending-order sorting of values
- Put original HashMap entries into newly created TreeMap using putAll() method
- Descending-order values :- Create another TreeMap object and pass Comparator as constructor-argument by providing/implementing/overriding code/logic for descending-order sorting of values
- Put original HashMap entries into newly created TreeMap using putAll() method
SortMapByValuesUsingTreeMap.java
package net.bench.resources.map.values.sorting.ways;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class SortMapByValuesUsingTreeMap {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 2. Sorting according to natural order of Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 Map Values in Ascending order
Map<String, Integer> sortedMapAsc = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
int comp = countryPopulation.get(str1) - countryPopulation.get(str2);
return comp == 0 ? 1 : comp;
}
});
// 2.2 put actual map to TreeMap for Ascending-order Value sorting
sortedMapAsc.putAll(countryPopulation);
// 2.3 print Map entries to console
sortedMapAsc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 3. Sorting according to reverse order of Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 Map Values in Descending order
Map<String, Integer> sortedMapDesc = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
int comp = countryPopulation.get(str2) - countryPopulation.get(str1);
return comp == 0 ? 1 : comp;
}
});
// 2.2 put actual map to TreeMap for Descending-order Value sorting
sortedMapDesc.putAll(countryPopulation);
// 2.3 print Map entries to console
sortedMapDesc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
2. Using ArrayList class & Collections.sort() method
- First, convert Map entries into List of Map Entry Set
- Ascending-order values :- Use Collections.sort() method by passing converted List of Map Entry Set as 1st argument and implement Comparator interface as 2nd argument by providing code/logic for ascending-order sorting of values
- Descending-order values :- Use Collections.sort() method by passing converted List of Map Entry Set as 1st argument and implement Comparator interface as 2nd argument by providing code/logic for descending-order sorting of values
SortMapByValuesUsingArrayList.java
package net.bench.resources.map.values.sorting.ways;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class SortMapByValuesUsingArrayList {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 1.4 convert Map to List of Map.Entry set
List<Map.Entry<String, Integer>> entrySetList = new ArrayList<>(
countryPopulation.entrySet());
// 2. Sorting according to natural order of Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 Ascending order sorting of Map Values
Collections.sort(entrySetList, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> es1, Entry<String, Integer> es2) {
return es1.getValue().compareTo(es2.getValue());
}
});
// 2.2 print Map entries
entrySetList.forEach(entry -> System.out.println(
"Key : " + entry.getKey() + "\t\t" +
"Value : " + entry.getValue()
));
// 3. Sorting according to reverse order of Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 Descending order sorting of Map Values
Collections.sort(entrySetList, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> es1, Entry<String, Integer> es2) {
return es2.getValue().compareTo(es1.getValue());
}
});
// 3.2 print Map entries
entrySetList.forEach(entry -> System.out.println(
"Key : " + entry.getKey() + "\t\t" +
"Value : " + entry.getValue()
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
3. Using TreeSet class
- Ascending-order values :- Create TreeSet object and pass Comparator as constructor-argument by providing/implementing/overriding code/logic for ascending-order sorting of values
- Put original Map Key-Set into newly created TreeSet using addAll() method
- Descending-order values :- Create another TreeSet object and pass Comparator as constructor-argument by providing/implementing/overriding code/logic for descending-order sorting of values
- Put original Map Key-Set into newly created TreeSet using addAll() method
SortMapByValuesUsingTreeSet.java
package net.bench.resources.map.values.sorting.ways;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortMapByValuesUsingTreeSet {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 2. Sorting according to natural order of Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 TreeSet - Ascending order Sorting by Map Values
SortedSet<String> mapValuesAsc = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
int comp = countryPopulation.get(str1) - countryPopulation.get(str2);
return comp == 0 ? 1 : comp;
}
});
// 2.2 add unsorted keySet to TreeSet for natural order sorting
mapValuesAsc.addAll(countryPopulation.keySet());
// 2.3 print Map entries in ascending-order
mapValuesAsc.forEach(key -> System.out.println(
"Key : " + key + "\t\t" +
"Value : " + countryPopulation.get(key)
));
// 3. Sorting according to reverse order of Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 TreeSet - Descending order Sorting by Map Values
SortedSet<String> mapValuesDesc = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
int comp = countryPopulation.get(str2) - countryPopulation.get(str1);
return comp == 0 ? 1 : comp;
}
});
// 3.2 add unsorted keySet to TreeSet for reverse-order sorting
mapValuesDesc.addAll(countryPopulation.keySet());
// 3.3 print Map entries in descending-order
mapValuesDesc.forEach(key -> System.out.println(
"Key : " + key + "\t\t" +
"Value : " + countryPopulation.get(key)
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
4. Java 8 – Lambda function
- First, convert Map entries into List of Map Entry Set
- Ascending-order values :- Use Collections.sort() method by passing converted List of Map Entry Set as 1st argument and 2nd argument as below lambda expression for ascending-order sorting of values
- (map1, map2) -> map1.getValue().compareTo(map2.getValue())
- Descending-order values :- Use Collections.sort() method by passing converted List of Map Entry Set as 1st argument and 2nd argument as below lambda expression for descending-order sorting of values
- (map1, map2) -> map2.getValue().compareTo(map1.getValue())
SortMapByKeysUsingJava8Lambda.java
package net.bench.resources.map.values.sorting.ways;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class SortMapByValuesUsingJava8Lambda {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 1.4 convert Map EntrySet into List
List<Map.Entry<String, Integer>> entrySetList = new LinkedList<>(
countryPopulation.entrySet());
// 2. Sorting according to natural order of Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 Ascending-order sorting of Map Values
Collections.sort(entrySetList,
(map1, map2) -> map1.getValue().compareTo(map2.getValue())
);
// 2.2 put sorted map into LinkedHashMap, by iterating
Map<String, Integer> tempMapAsc = new LinkedHashMap<>();
// 2.3 iterate and store in newly created LinkedHashMap
for (Map.Entry<String, Integer> map : entrySetList) {
tempMapAsc.put(map.getKey(), map.getValue());
}
// 2.4 print Map entries to console
tempMapAsc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 3. Sorting according to reverse order of Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 Descending-order sorting of Map Values
Collections.sort(entrySetList,
(map1, map2) -> map2.getValue().compareTo(map1.getValue())
);
// 3.2 put sorted map into LinkedHashMap, by iterating
Map<String, Integer> tempMapDesc = new LinkedHashMap<>();
// 3.3 iterate and store in newly created LinkedHashMap
for (Map.Entry<String, Integer> map : entrySetList) {
tempMapDesc.put(map.getKey(), map.getValue());
}
// 3.4 print Map entries to console
tempMapDesc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
5. Java 8 – Stream sorted() method
- In this approach, we are going to use Stream‘s sorted() method for sorting Map Values by passing lambda expression as argument to sorted() method
- Ascending order sorting :- for natural order of values pass below lambda expression,
- (map1, map2) -> map1.getValue().compareTo(map2.getValue())
- Descending order sorting :- for reverse order of values pass below lambda expression,
- (map1, map2) -> map2.getValue().compareTo(map1.getValue())
SortMapByKeysUsingStreamSortedMethod.java
package net.bench.resources.map.values.sorting.ways;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class SortMapByValuesUsingStreamSortedMethod {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 2. Sorting according to natural order of Map Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 Stream.sorted - Ascending order of Map Values
Map<String, Integer> tempMapAsc = countryPopulation
.entrySet()
.stream()
.sorted(
(map1, map2) -> map1.getValue().compareTo(map2.getValue())
)
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(es1, es2) -> es1, LinkedHashMap::new
)
);
// 2.2 print Map entries
tempMapAsc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 3. Sorting according to reverse order of Map Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 Stream.sorted - Descending order of Map Values
Map<String, Integer> tempMapDesc = countryPopulation
.entrySet()
.stream()
.sorted(
(map1, map2) -> map2.getValue().compareTo(map1.getValue())
)
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(es1, es2) -> es1, LinkedHashMap::new
)
);
// 3.2 print Map entries
tempMapDesc.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
6. Java 8 – Map.Entry.comparingByKey() comparator
- In this approach, we are going to use Stream‘s sorted() method for sorting Map Values by passing comparator as argument to sorted() method
- For natural order of values pass Map.Entry.comparingByValue() comparator
- For reverse order of values pass Map.Entry.comparingByValue(Comparator.reverseOrder()) comparator
SortMapEntryUsingComparingByValue.java
package net.bench.resources.map.values.sorting.ways;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
public class SortMapEntryUsingComparingByValue {
public static void main(String[] args) {
// 1. creating HashMap object of type <String, Integer>
Map<String, Integer> countryPopulation = new HashMap<>();
// 1.1 adding key-value pairs to HashMap object
countryPopulation.put("Indian", 382357386);
countryPopulation.put("America", 332429717);
countryPopulation.put("Russia", 146748590);
countryPopulation.put("Brazil", 213728559);
countryPopulation.put("Pakistan", 220892331);
// 1.2 print - before sorting - random order
System.out.println("Before Sorting - Random order :- \n");
// 1.3 print Map entries to console
countryPopulation.forEach((key, value) -> System.out.println(
"Key : " + key + "\t\t" + "Value : " + value
));
// 2. Sorting according to natural order of Map Values
System.out.println("\n\nSorted according to "
+ "natural order of Values :- \n");
// 2.1 Ascending-order sorting using Map.Entry.comparingByValue()
countryPopulation
.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.forEach(entry -> System.out.println(
"Key : " + entry.getKey() + "\t\t" +
"Value : " + entry.getValue()
));
// 3. Sorting according to reverse order of Map Values
System.out.println("\n\nSorted according to "
+ "reverse order of Values :- \n");
// 3.1 Descending-order sorting using Map.Entry.comparingByValue()
countryPopulation
.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) //reverse
.forEach(entry -> System.out.println(
"Key : " + entry.getKey() + "\t\t" +
"Value : " + entry.getValue()
));
}
}
Output:
Before Sorting - Random order :-
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Brazil Value : 213728559
Key : Indian Value : 382357386
Key : Russia Value : 146748590
Sorted according to natural order of Values :-
Key : Russia Value : 146748590
Key : Brazil Value : 213728559
Key : Pakistan Value : 220892331
Key : America Value : 332429717
Key : Indian Value : 382357386
Sorted according to reverse order of Values :-
Key : Indian Value : 382357386
Key : America Value : 332429717
Key : Pakistan Value : 220892331
Key : Brazil Value : 213728559
Key : Russia Value : 146748590
Important points to remember about Map :
- HashMap stores entries (Key-Value pairs) in random-order of Keys
- LinkedHashMap stores entries (Key-Value pairs) as per insertion-order of Keys
- TreeMap stores entries (Key-Value pairs) in sorted-order of Keys
Related Articles:
- Java 8 – How to Sort HashMap Key-Value pairs by its Key in ascending & descending order
- Java 8 – How to Sort HashMap Key-Value pairs by its Value in ascending & descending order
- Java 8 – Sorting HashMap entries by its Key and Value
- Java 8 – How to Sort a Map entries by its Key – 6 ways
- Java 8 – How to Sort a Map entries by its Value – 6 ways
- Java 8 – How to sort LinkedHashMap entries by its Key in ascending/descending order ?
- Java 8 – How to sort LinkedHashMap entries by its Value in ascending/descending order ?
- Java 8 – How to sort TreeMap entries in descending order
References:
- https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
- https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
- https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
- https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
- https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html
- https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted–
- https://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html#comparingByKey-java.util.Comparator-
- https://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html#comparingByValue-java.util.Comparator-
Happy Coding !!
Happy Learning !!