HashMap in Java: 5 fatale Fehler beim Durchlaufen und wie man sie vermeidet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: HashMap – Freund oder Feind?



Jeder Java-Entwickler stößt früher oder später auf HashMap. Dies ist wohl die beliebteste Implementierung des Map-Interface in Java. Aber hier ist das Paradoxon: Jeder weiß, wie man ein Element in die Map einfügt, aber wenn es um das Durchlaufen (Iteration) geht, beginnt das absolute Chaos. Die Frage "Iterate through a HashMap" auf Stack Overflow hat tausende Aufrufe, und die Anzahl der Fehler in realen Projekten ist enorm.



In diesem Artikel analysieren wir die 5 gefährlichsten Fehler beim Durchlaufen einer HashMap in Java, die zum Absturz der Anwendung, Datenverlust und unlesbarem Code führen können. Sie erfahren nicht nur wie es falsch geht, sondern erhalten auch funktionierende Vorlagen für jeden Fall. Los geht's!



Fehler Nr. 1: ConcurrentModificationException – "Lösche während der Fahrt"



Was ist das Problem?

Der klassischste Fehler. Sie iterieren über eine HashMap und versuchen, ein Element mit map.remove(key) zu entfernen. In 90% der Fälle führt dies zu einer ConcurrentModificationException.



// ❌ GEFÄHRLICH: löst eine Exception aus!HashMap<String, Integer> scores = new HashMap<>();scores.put("Alice", 90);scores.put("Bob", 50);scores.put("Charlie", 70);

for (String name : scores.keySet()) { if (scores.get(name) < 60) { scores.remove(name); // ConcurrentModificationException! }}


Warum passiert das?

Der interne Iterator der HashMap führt einen Modifikationszähler (modCount). Wenn Sie ein Element direkt über die Collection entfernen, ändert sich der Zähler, aber der Iterator weiß nichts davon. Bei der nächsten Iteration prüft er: "Hey, der Zähler stimmt nicht überein! Exception werfen."



Wie behebt man das?

Verwenden Sie Iterator mit seiner remove()-Methode:



// ✅ RICHTIG: Iterator verwendenHashMap<String, Integer> scores = new HashMap<>();scores.put("Alice", 90);scores.put("Bob", 50);scores.put("Charlie", 70);

Iterator<Map.Entry<String, Integer>> iterator = scores.entrySet().iterator();while (iterator.hasNext()) { Map.Entry<String, Integer> entry = iterator.next(); if (entry.getValue() < 60) { iterator.remove(); // Sicheres Entfernen! }}


Seit Java 8 gibt es eine noch elegantere Methode – removeIf():



// ✅ NOCH BESSER: removeIf (Java 8+)scores.entrySet().removeIf(entry -> entry.getValue() < 60);


Fehler Nr. 2: Langsames Durchlaufen mit keySet() und get()



Was ist das Problem?

Viele Anfänger machen Folgendes:



// ❌ LANGSAM: keySet() + get() – doppelte Suchefor (String key : map.keySet()) {    System.out.println("Key: " + key + ", Value: " + map.get(key));}


Auf den ersten Blick funktioniert alles. Das Problem ist jedoch, dass map.get(key) intern erneut den Hash sucht und durch den Bucket läuft. Bei jedem Schleifendurchlauf führen Sie zwei Aufrufe an die HashMap statt einem. Bei kleinen Maps ist das kaum spürbar, aber bei Hunderttausenden von Einträgen führt das zu einem Leistungsverlust von bis zu 30-40%.



Wie behebt man das?

Verwenden Sie immer entrySet() – es gibt die Schlüssel-Wert-Paare in einem Durchlauf zurück:



// ✅ SCHNELL: entrySet() – ein Durchlauffor (Map.Entry<String, Integer> entry : map.entrySet()) {    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}


Oder verwenden Sie forEach seit Java 8:



// ✅ KNAPP: forEach (Java 8+)map.forEach((key, value) -> {    System.out.println("Key: " + key + ", Value: " + value);});


Fehler Nr. 3: Verwirrung über die Reihenfolge der Elemente



Was ist das Problem?

Sie haben Code geschrieben, der eine HashMap durchläuft, und erwarten, dass die Elemente in der Reihenfolge des Hinzufügens erscheinen. Aber Sie erhalten eine völlig andere Sequenz. Dies führt zu Bugs, die

Blogs

Buchempfehlungen