Sorting Map by Values in Java: How to Avoid Old Pitfalls (and New Ones Too)
\n\n“I need to sort a HashMap by values!” — this question on Stack Overflow gathers thousands of views and dozens of answers. It seems so simple, right? Just take a Map, sort it by values()… and get a headache. Because sorting a Map by values in Java is a task where beginners (and even experienced developers) make the same mistakes over and over again.
In this article, we will break down the 5 most common errors when sorting a HashMap by values, show the correct solutions, and provide ready-to-use code templates. Let's go!
\n\nMistake #1: Naively Trying to Sort the HashMap Itself
\n\nThe most common mistake is thinking that a HashMap can be sorted “in place.” HashMap does not guarantee element order — this is its fundamental property. You cannot simply call sort() on a HashMap because it doesn't have such a method.
Here's how NOT to do it:
\n\n// ❌ ERROR: HashMap cannot be sorted directly\nMap<String, Integer> scores = new HashMap<>();\nscores.put("Alice", 95);\nscores.put("Bob", 80);\nscores.put("Charlie", 90);\n\n// This method doesn't exist!\n// scores.sort(...); // Compilation error\n\nWhy doesn't this work? HashMap uses hashing to store key-value pairs. The order is determined by the hash codes of the keys and can change when new elements are added. Sorting a Map by values is only possible by creating a new data structure — for example, LinkedHashMap.
Correct Solution: Create a New LinkedHashMap
\n\n// ✅ CORRECT: sort Entry and store in LinkedHashMap\nMap<String, Integer> sortedMap = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue,\n (e1, e2) -> e1, // resolve conflicts (if keys are duplicated)\n LinkedHashMap::new // preserve insertion order\n ));\n\nSystem.out.println(sortedMap);\n// {Bob=80, Charlie=90, Alice=95} — sorted in ascending order!\n\nMistake #2: Forgetting About LinkedHashMap When Collecting
\n\nEven experienced Java developers sometimes write code like this:
\n\n// ⚠️ ALMOST CORRECT, but there's a nuance\nMap<String, Integer> result = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue\n )); // By default, Collectors.toMap() creates a HashMap!\n\nWhat's the catch? Collectors.toMap() without specifying a supplier creates a HashMap. And HashMap does not guarantee order! Your sorting will be performed, but the result may appear unsorted. This is one of the most insidious Java errors when sorting a Map.
How to Fix It
\n\nAlways explicitly specify LinkedHashMap::new as the fourth argument:
// ✅ GUARANTEED CORRECT\nMap<String, Integer> result = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue,\n (oldVal, newVal) -> oldVal,\n LinkedHashMap::new // Key point!\n ));\n\nMistake #3: Sorting by Values When They Are Not Comparable
\n\nLet's say you have a Map<String, CustomObject>. You write:
// ❌ ERROR: CustomObject does not implement Comparable\nMap<String, CustomObject> map = new HashMap<>();\n// ...\nmap.entrySet().stream()\n .sorted(Map.Entry.comparingByValue()) // Compilation error!\n