Understanding java.util.ConcurrentModificationException and Safe Ways to Remove Elements from a List
This article explains why using a foreach loop to remove elements from a Java List triggers java.util.ConcurrentModificationException, analyzes the underlying iterator mechanism, and presents three safe alternatives: iterator.remove(), forward-index loop with index adjustment, and reverse-index loop.
This article discusses a common interview question about encountering java.util.ConcurrentModificationException when removing elements from a List using a foreach loop.
It shows the problematic code, explains that foreach internally uses an Iterator whose hasNext() and next() methods check a modification count ( modCount ) against an expected count ( expectedModCount ), and demonstrates how removing an element inside the loop changes modCount , causing the exception.
Problematic code example:
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);
}The article then presents three correct ways to remove elements safely:
Use Iterator 's remove() method.
Iterate with a forward for loop using an index and adjust the index after removal.
Iterate with a reverse for loop, which avoids index shifting.
Example using Iterator.remove() :
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);
}Output: [CSDN, 掘金]
Example using a forward index loop (with index correction):
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; // adjust index after removal
}
}
System.out.println(platformList);
}Example using a reverse index loop (no index adjustment needed):
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);
}Each method is illustrated with complete Java code examples and the resulting output, showing how they avoid the ConcurrentModificationException .
Additional notes include a brief look at the source code of Iterator.remove() , which synchronizes modCount and expectedModCount , and references to related interview resources.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java 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.