Java 8 – How to Sort a Map entries by its Value – 6 ways

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,

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 8Map.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

References:

Happy Coding !!
Happy Learning !!

Java 8 - How to sort LinkedHashMap entries by its Key ?
Java 8 – How to Sort a Map entries by its Key – 6 ways