Fundamentals 6 min read

Why Removing Elements from a HashMap During a For‑Each Loop Causes ConcurrentModificationException and How to Fix It

Iterating a HashMap with a for‑each loop while calling its remove method triggers a ConcurrentModificationException because the loop uses an internal iterator that becomes inconsistent with the map’s modCount, and the article explains the cause, shows decompiled code, and provides correct removal approaches using the iterator or removeIf.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
Why Removing Elements from a HashMap During a For‑Each Loop Causes ConcurrentModificationException and How to Fix It

When a HashMap is traversed with a for‑each loop over entrySet() and the map’s remove method is invoked at the same time, a ConcurrentModificationException is thrown even in a single‑threaded context.

Reproduction

public static void main(String[] args) {
    Map
map = new HashMap<>();
    map.put("a", 1);
    map.put("b", "b");
    for (Map.Entry
entry : map.entrySet()) {
        if (entry.getKey().equals("a")){
            map.remove("a");
        }
    }
}

Running the above code on Java 17 produces the following stack trace:

Exception in thread "main" java.util.ConcurrentModificationException
  at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1597)
  at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1630)
  at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1628)
  at com.example.springcloudtest.spring.postprocessor.Test.main(Test.java:20)

Root cause

The for‑each loop internally uses the iterator java.util.HashMap.EntryIterator . The iterator checks the map’s modCount against its own expectedModCount . Calling HashMap.remove(Object) updates the map’s modCount but does not update the iterator’s expectedModCount , causing the mismatch and the exception.

Decompiled version of the loop (without syntactic sugar) shows the explicit iterator usage:

public class Test {
    public static void main(String[] args) {
        Map
map = new HashMap();
        map.put("a", 1);
        map.put("b", "b");
        Iterator var2 = map.entrySet().iterator();
        while(var2.hasNext()) {
            Entry
entry = (Entry)var2.next();
            if (((String)entry.getKey()).equals("a")) {
                map.remove("a");
            }
        }
    }
}

Therefore, when iterating with an iterator, removal must be performed through the iterator itself, not through the collection’s remove method.

Corrected examples

1. Use the iterator’s remove() method:

public static void main(String[] args) {
    Map
map = new HashMap<>();
    map.put("a", 1);
    map.put("b", "b");
    System.out.println(map);
    Iterator
> iterator = map.entrySet().iterator();
    while (iterator.hasNext()){
        Map.Entry
next = iterator.next();
        if (next.getKey().equals("a")){
            iterator.remove();
        }
    }
    System.out.println("删除后:" + map);
}

2. Use Collection.removeIf directly on the entry set:

public static void main(String[] args) {
    Map
map = new HashMap<>();
    map.put("a", 1);
    map.put("b", "b");
    map.entrySet().removeIf(entry -> entry.getKey().equals("a"));
    System.out.println(map);
}

Summary

The for‑each loop in Java is syntactic sugar for an iterator; removing elements via the map’s own remove while iterating breaks the iterator’s consistency check and triggers ConcurrentModificationException . Use the iterator’s remove() method or removeIf to safely delete entries during iteration.

JavaHashMapCollectionsIteratorConcurrentModificationExceptionfor-each
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.