Backend Development 7 min read

How to Avoid java.util.ConcurrentModificationException When Removing Elements from a List

This article explains why a foreach loop over an ArrayList can throw java.util.ConcurrentModificationException when removing elements, analyzes the underlying iterator mechanism, and presents three safe alternatives—using Iterator.remove(), a forward-index for loop with index correction, and a reverse for loop—to modify collections without errors.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
How to Avoid java.util.ConcurrentModificationException When Removing Elements from a List

This article shares a common interview question about encountering a java.util.ConcurrentModificationException when trying to remove elements from an ArrayList using a foreach loop.

It first shows the naive code that causes the exception:

public static void main(String[] args) {
    List
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 java.util.ConcurrentModificationException because the foreach loop internally uses an Iterator , and removing an element directly from the list changes the internal modCount without updating the iterator’s expectedModCount .

The article then explains the iterator’s bytecode, showing that each call to next() invokes checkForComodification() , which compares modCount and expectedModCount . After the explicit remove() call on the list, modCount becomes 4 while expectedModCount remains 3, triggering the exception on the next iteration.

To avoid this problem, three safe approaches are presented:

1. Use Iterator.remove()

By iterating with an Iterator and calling its remove() method, the iterator updates expectedModCount automatically.

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

The output is [CSDN, 掘金] .

2. Use a forward-index for loop

Iterate by index and adjust the index after removal to avoid skipping elements.

public static void main(String[] args) {
    List
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; // correct the index after removal
        }
    }
    System.out.println(platformList);
}

Adjusting i ensures the next element is not missed.

3. Use a reverse for loop

Iterate from the end of the list toward the beginning; removal does not affect the indices of the yet‑to‑be‑processed elements.

public static void main(String[] args) {
    List
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);
}

This method avoids index correction because elements after the current index are already processed.

In summary, the article demonstrates why modifying a collection during a foreach iteration leads to ConcurrentModificationException and provides three reliable ways—using Iterator.remove() , a forward-index loop with index adjustment, and a reverse loop—to safely remove elements from a list.

JavaArrayListIteratorConcurrentModificationExceptionLoop
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

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.