HashMap Sorting by Value in Java
Problem
Sorting a map's entries by value — instead of by key — answers a different, equally common question: which entries have the largest or smallest values, not which keys come first alphabetically.
Given a HashMap of word counts, print its entries sorted by count, highest first.
Java Program
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HashMapSortingByValue {
public static void main(String[] args) {
Map<String, Integer> counts = new HashMap<>();
counts.put("fox", 2);
counts.put("the", 3);
counts.put("dog", 1);
List<Map.Entry<String, Integer>> entries = new ArrayList<>(counts.entrySet());
entries.sort((e1, e2) -> e2.getValue() - e1.getValue()); // descending: higher counts first
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}Output
Core Logic
The exact same copy-then-sort technique used for sorting by key works here too — only the comparator changes, from comparing keys to comparing values.
- 1
new ArrayList<>(counts.entrySet())copies the map's entries into a sortable List, same as sorting by key. - 2
(e1, e2) -> e2.getValue() - e1.getValue()is a comparator lambda that compares each pair of entries by their values. - 3Subtracting the second entry's value from the first's, instead of the other way around, sorts descending — higher counts come before lower ones.
- 4Sorting the List with that comparator and printing it afterward shows the word with the highest count first.
fox: 2, the: 3, and dog: 1, sorting by value descending puts the first, then fox, then dog.Key Point: Comparing values instead of keys, and subtracting in the opposite order for a descending sort, is the entire difference from sorting by key — the copy-into-a-List technique underneath is identical either way.
Why: Copying the n entries into a List costs O(n), and sorting that List costs O(n log n), which dominates the total.
Key Concepts
Approach 2: Java 8
import java.util.HashMap;
import java.util.Map;
public class HashMapSortingByValueStream {
public static void main(String[] args) {
Map<String, Integer> counts = new HashMap<>();
counts.put("fox", 2);
counts.put("the", 3);
counts.put("dog", 1);
// Sorts by value using the built-in comparator, reversed for descending order
counts.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
}
}
Output
Core Logic
Streaming the entrySet and sorting it with the built-in Map.Entry.comparingByValue() comparator expresses the same sort as a pipeline, without writing the comparison lambda by hand.
- 1
counts.entrySet().stream()opens a stream directly over the map's entries — no separate List needs to be built first. - 2
Map.Entry.<String, Integer>comparingByValue()is a ready-made comparator that compares two entries by their values, replacing the manual(e1, e2) -> e2.getValue() - e1.getValue()lambda. - 3
.reversed()flips that comparator to descending order, sincecomparingByValue()alone sorts ascending. - 4
.forEach(...)prints each sorted entry directly, without collecting the sorted stream into a List first.
{fox: 2, the: 3, dog: 1}'s entries through the reversed value comparator sorts them the same way — the, then fox, then dog.Key Point: Map.Entry.comparingByValue() is the standard-library comparator built specifically for this — reaching for it instead of a hand-written lambda avoids getting the subtraction direction backwards, an easy mistake in the manual version.
Why: sorted() still needs to buffer and sort all n entries internally before forEach() can process them in order, the same overall cost as the manual copy-and-sort.