Map nach Werten in Java sortieren: Wie man nicht auf alte (und neue) Rechen fällt
\n\n„Ich muss eine HashMap nach Werten sortieren!“ – diese Frage auf Stack Overflow sammelt tausende Aufrufe und Dutzende Antworten. Was könnte einfacher sein? Man nimmt eine Map, sortiert sie nach values() … und bekommt Kopfschmerzen. Denn das Sortieren einer Map nach Werten in Java ist eine Aufgabe, bei der Anfänger (und sogar erfahrene Entwickler) immer wieder dieselben Fehler machen.
In diesem Artikel analysieren wir die 5 häufigsten Fehler beim Sortieren einer HashMap nach Werten, zeigen die richtigen Lösungen und geben fertige Code-Vorlagen. Los geht‘s!
\n\nFehler Nr. 1: Naiver Versuch, die HashMap selbst zu sortieren
\n\nDer häufigste Fehler ist zu glauben, dass man eine HashMap „an Ort und Stelle“ sortieren kann. Eine HashMap garantiert keine Reihenfolge der Elemente – das ist ihre grundlegende Eigenschaft. Man kann nicht einfach sort() auf einer HashMap aufrufen, da sie keine solche Methode hat.
So sollte man es NICHT machen:
\n\n// ❌ FEHLER: HashMap kann nicht direkt sortiert werden\nMap<String, Integer> scores = new HashMap<>();\nscores.put("Alice", 95);\nscores.put("Bob", 80);\nscores.put("Charlie", 90);\n\n// Diese Methode existiert nicht!\n// scores.sort(...); // Kompilierungsfehler\n\nWarum funktioniert das nicht? HashMap verwendet Hashing zum Speichern von Schlüssel-Wert-Paaren. Die Reihenfolge wird durch die Hash-Codes der Schlüssel bestimmt und kann sich beim Hinzufügen neuer Elemente ändern. Das Sortieren einer Map nach Werten ist nur durch die Erstellung einer neuen Datenstruktur möglich – zum Beispiel einer LinkedHashMap.
Richtige Lösung: Eine neue LinkedHashMap erstellen
\n\n// ✅ RICHTIG: Entry sortieren und in LinkedHashMap speichern\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, // Konflikte auflösen (falls Schlüssel dupliziert werden)\n LinkedHashMap::new // Einfügereihenfolge beibehalten\n ));\n\nSystem.out.println(sortedMap);\n// {Bob=80, Charlie=90, Alice=95} – aufsteigend sortiert!\n\nFehler Nr. 2: LinkedHashMap beim Sammeln vergessen
\n\nSogar erfahrene Java-Entwickler schreiben manchmal diesen Code:
\n\n// ⚠️ FAST RICHTIG, aber es gibt einen Haken\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 )); // Standardmäßig erzeugt Collectors.toMap() eine HashMap!\n\nWas ist der Haken? Collectors.toMap() ohne Angabe eines Lieferanten (supplier) erzeugt eine HashMap. Und eine HashMap garantiert keine Reihenfolge! Ihre Sortierung wird durchgeführt, aber das Ergebnis kann unsortiert aussehen. Dies ist einer der tückischsten Java-Fehler beim Sortieren von Maps.
Wie man es behebt
\n\nGeben Sie immer explizit LinkedHashMap::new als viertes Argument an:
// ✅ GARANTIERT RICHTIG\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 // Entscheidender Punkt!\n ));\n\nFehler Nr. 3: Sortieren nach Werten, wenn diese nicht Comparable sind
\n\nAngenommen, Sie haben eine Map<String, CustomObject>. Sie schreiben:
// ❌ FEHLER: CustomObject implementiert Comparable nicht\nMap<String, CustomObject> map = new HashMap<>();\n// ...\nmap.entrySet().stream()\n .sorted(Map.Entry.comparingByValue()) // Kompilierungsfehler!\n