When working with maps in Java, sorting them by their values is a common task that can enhance data readability and organization. Typically, Java's Map
interface does not directly support ordering by values, as it mainly focuses on key-based operations. This necessitates creative approaches to achieve such functionality, often involving converting the map into a structure that supports ordering.
In this article, you will learn how to sort a Map
by values in Java. Discover different methods to accomplish this task, including using a Stream
combined with comparators and transforming the map into a list of entries for sorting. Each section provides practical code examples to illustrate the execution of these methods, ensuring you can confidently apply them to your own projects.
Convert the Map into a Stream of its entries.
Sort the Stream by comparing the Map values.
Collect the results into a new LinkedHashMap to preserve the sorted order.
import java.util.*;
import java.util.stream.Collectors;
Map<String, Integer> unsortedMap = new HashMap<>();
unsortedMap.put("Apple", 10);
unsortedMap.put("Orange", 5);
unsortedMap.put("Banana", 7);
Map<String, Integer> sortedMap = unsortedMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new
));
sortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
This code snippet sorts the unsortedMap
by its values in ascending order. The sorted(Map.Entry.comparingByValue())
handles the sorting operation. Finally, the results are collected into a LinkedHashMap
to preserve the order of insertion, which is now sorted by value.
Integrate a custom comparator for custom sorting, such as descending order.
Use the same Stream conversion to sort the entries.
Collect the entries back to a map that maintains the order.
Map<String, Integer> customSortedMap = unsortedMap.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new
));
customSortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
This variation adds a .reversed()
to the comparator, sorting the map in descending order based on the values. The rest of the flow remains the same, ensuring the map is collected in a LinkedHashMap
to maintain the order.
Use a TreeSet initialized with a custom Comparator based on Map values.
Insert all Map entries into the TreeSet.
Extract a sorted Map from the TreeSet entries.
Comparator<Map.Entry<String, Integer>> valueComparator = (e1, e2) -> e1.getValue().compareTo(e2.getValue());
Set<Map.Entry<String, Integer>> sortedEntries = new TreeSet<>(valueComparator);
sortedEntries.addAll(unsortedMap.entrySet());
// Creating the LinkedHashMap from TreeSet
Map<String, Integer> treeMapSorted = sortedEntries.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new
));
treeMapSorted.forEach((key, value) -> System.out.println(key + ": " + value));
Here, the strategy involves using a TreeSet
with a Comparator
that sorts the entries as they are added. The TreeSet maintains the natural sorting order as defined by the comparator. The sorted entries are then streamed and collected into a LinkedHashMap
to retain the order in the map.
Sorting a Map by its values in Java requires transformining the map data into a form that supports sorting, such as streams or sets. The techniques discussed—utilizing the Stream API for direct sorting and using a TreeSet for custom ordering—provide robust solutions to handle various sorting requirements. Apply these methods effectively in your programming tasks to manage and organize map entries based on their values, thus facilitating better data manipulation and presentation in your applications.