Fundamentals 7 min read

Why Does foreach Throw ConcurrentModificationException and How to Fix It?

During a Java interview, a common mistake of using a foreach loop to remove elements from an ArrayList triggers a ConcurrentModificationException; this article explains the underlying iterator mechanism, shows the bytecode behavior, and presents four safe alternatives—including iterator.remove(), forward and backward for-loops—to avoid the error.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Does foreach Throw ConcurrentModificationException and How to Fix It?

This article summarizes a typical interview question about why a foreach loop can cause a java.util.ConcurrentModificationException when removing elements from an ArrayList and how to solve it.

1. Common mistake

Many beginners write code like the following:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");
    for (String platform : platformList) {
        if (platform.equals("博客园")) {
            platformList.remove(platform);
        }
    }
    System.out.println(platformList);
}

Running this code throws a java.util.ConcurrentModificationException because the foreach loop internally uses an Iterator whose core methods are hasNext() and next().

The generated bytecode (illustrated below) shows that the foreach loop is compiled to use an Iterator:

When Iterator.next() is called, it first invokes checkForComodification(), which compares modCount and expectedModCount. In the example, both start at 3, but after executing platformList.remove(platform), modCount becomes 4 while expectedModCount remains 3, causing the exception.

2. Use Iterator.remove()

Removing elements via the iterator’s own remove() method keeps modCount and expectedModCount in sync:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");
    Iterator<String> iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }
    System.out.println(platformList);
}

Output: [CSDN, 掘金] Each removal updates expectedModCount to match the new modCount, preventing the exception.

3. Use a forward for loop

Iterating with an index and adjusting the index after removal also works:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");
    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);
        if (item.equals("博客园")) {
            platformList.remove(i);
            i = i - 1; // adjust index after removal
        }
    }
    System.out.println(platformList);
}

The index adjustment is necessary because removing an element shifts subsequent elements left, otherwise the next element would be skipped.

4. Use a backward for loop

Iterating from the end to the beginning avoids the need for index correction:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");
    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);
        if (item.equals("掘金")) {
            platformList.remove(i);
        }
    }
    System.out.println(platformList);
}

Since the loop proceeds from high to low indices, removal does not affect the yet‑to‑be‑visited elements.

5. References

https://blog.csdn.net/zjwcdd/article/details/51513879 https://blog.csdn.net/wangjun5159/article/details/61415358
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaArrayListIteratorfor loopConcurrentModificationException
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

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.