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.
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
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
