HashMap in Java: 5 Fatal Errors When Iterating and How to Avoid Them

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: HashMap — Friend or Foe?



Every Java developer sooner or later encounters HashMap. This is perhaps the most popular implementation of the Map interface in Java. But here's the paradox: everyone knows how to put an element into a map, but when it comes to iterating over it, real chaos begins. The question "Iterate through a HashMap" on Stack Overflow has thousands of views, and the number of errors in real projects is off the charts.



In this article, we will break down 5 most dangerous errors when iterating over a HashMap in Java, which can lead to application crashes, data loss, and unreadable code. You will learn not only how not to do it, but also get working patterns for each case. Let's go!



Error #1: ConcurrentModificationException — "Removing on the Fly"



What's the problem?

The most classic error. You iterate over a HashMap and try to remove an element using map.remove(key). In 90% of cases, this leads to a ConcurrentModificationException.



// ❌ DANGEROUS: will throw an exception!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! }}


Why does this happen?

The internal iterator of HashMap maintains a modification counter (modCount). When you remove an element directly through the collection, the counter changes, but the iterator doesn't know about it. On the next iteration, it checks: "Hey, the counter doesn't match! Throwing an exception."



How to fix it?

Use the Iterator with its remove() method:



// ✅ CORRECT: use IteratorHashMap<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(); // Safe removal! }}


Since Java 8, there is an even more elegant way — removeIf():



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


Error #2: Slow Iteration Using keySet() and get()



What's the problem?

Many beginners do this:



// ❌ SLOW: keySet() + get() — double lookupfor (String key : map.keySet()) {    System.out.println("Key: " + key + ", Value: " + map.get(key));}


At first glance, it works. But the problem is that map.get(key) internally searches for the hash again and traverses the bucket. With each loop iteration, you make two calls to the HashMap instead of one. For small maps, this is unnoticeable, but with hundreds of thousands of entries, it's a performance loss of up to 30-40%.



How to fix it?

Always use entrySet() — it returns key-value pairs in a single pass:



// ✅ FAST: entrySet() — one passfor (Map.Entry<String, Integer> entry : map.entrySet()) {    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}


Or use forEach from Java 8:



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


Error #3: Confusion with Element Order



What's the problem?

You wrote code that iterates over a HashMap and expect elements to be in insertion order. But you get a completely different sequence. This leads to bugs that are

Blogs

Book Recommendations