Fundamentals 9 min read

Can You Remove Items Inside a Java foreach Loop? Why It Fails and How to Fix It

This article explores how Java's foreach loop handles collection traversal, demonstrates why removing or modifying elements directly within a foreach causes ConcurrentModificationException, compares it with traditional for loops, and shows the correct way to delete or update elements using an iterator or element properties.

Programmer DD
Programmer DD
Programmer DD
Can You Remove Items Inside a Java foreach Loop? Why It Fails and How to Fix It

Iterating Elements

First, example code for iterating an array and an ArrayList using enhanced for loops.

String[] array = {"1","2","3"};
for (String i : array) {
    System.out.println(i);
}

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
for (String i : list) {
    System.out.println(i);
}

The output is:

1
2
3
111
222
333

Decompiled bytecode shows that array iteration uses a traditional for loop, while collection iteration uses an Iterator.

Removing Elements

Using a classic for loop

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
for (int i = 0; i < list.size(); i++) {
    list.remove("222");
}
log.info(list.toString());

Result: the element is removed successfully.

Using foreach

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
for (String i : list) {
    list.remove("222");
}
log.info(list.toString());

This throws java.util.ConcurrentModificationException because the iterator's expected modCount does not match the list's modCount after removal.

Reason

The iterator records the collection's modCount at the start of iteration; calling list.remove increments the list's modCount, causing a mismatch and the exception.

Correct removal with iterator

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String next = it.next();
    if (next.equals("222")) {
        it.remove();
    }
}
log.info(list.toString());

Modifying Elements

Using classic for

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
for (int i = 0; i < list.size(); i++) {
    list.set(i, "444");
}
log.info(list.toString());

All elements become "444".

Using foreach

ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
for (String i : list) {
    i = "444";
}
log.info(list.toString());

The list remains unchanged because reassigning the loop variable does not affect the collection.

Modifying Object Properties in foreach

Define a Student class with age and name fields and corresponding getters/setters.

public class Student {
    private int age;
    private String name;
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Student() {}
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
Student s1 = new Student(1, "huge");
Student s2 = new Student(1, "xiaoyao");
List<Student> studentList = new ArrayList<>();
studentList.add(s1);
studentList.add(s2);
for (Student stu : studentList) {
    stu.setName("jingtian");
}
System.out.println(s1.getName());
System.out.println(s2.getName());

The output shows both names changed to "jingtian", demonstrating that while you cannot replace objects in a foreach loop, you can modify their internal state.

Summary

Both for and foreach can iterate arrays and collections; for may be more efficient in complex loops.

foreach cannot delete or replace collection elements directly; classic for can.

Both loops can modify the properties of objects contained in the collection.

Therefore, the classic for loop offers greater flexibility.

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.

javaIteratorforeachCollectionConcurrentModificationException/loop
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.