Understanding Java for‑loop vs foreach: Traversal, Deletion, and Modification
This article explains how Java's traditional for loop and the enhanced foreach loop differ when iterating collections, how to correctly delete elements, why modifying collection elements directly with foreach fails, and how to safely modify element attributes using iterators or object methods.
Java developers often wonder when to use the classic for loop versus the enhanced foreach (for‑each) loop. Both can iterate arrays and collections, but their behavior diverges when the loop body modifies the underlying data.
1) Traversing elements
Example code:
String[] array = {"1", "2", "3"};
for (String i : array) {
System.out.println(i);
}
ArrayList
list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
for (String i : list) {
System.out.println(i);
}The output is the expected sequence of values. The compiled bytecode shows that array traversal is translated to an index‑based for loop, while collection traversal uses an Iterator .
2) Deleting elements
Using a classic for loop:
ArrayList
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 (log excerpt):
[111, 222, 333]
[111, 333]The deletion succeeds because the loop controls the index directly.
Attempting the same with foreach throws a ConcurrentModificationException :
ArrayList
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());Exception output:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
...The failure occurs because the iterator detects that the collection’s internal modCount changed without using the iterator’s own remove() method.
Correct deletion with an iterator:
ArrayList
list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
Iterator
it = list.iterator();
while (it.hasNext()) {
String next = it.next();
if (next.equals("222")) {
it.remove(); // iterator‑based removal
}
}
log.info(list.toString());Result:
[111, 222, 333]
[111, 333]3) Modifying elements
With a classic for loop you can replace each element:
ArrayList
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());Result shows all entries become 444 . Using foreach to assign a new value to the loop variable does **not** modify the list because the variable holds a copy of the reference:
ArrayList
list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
log.info(list.toString());
for (String i : list) {
i = "444"; // no effect on the list
}
log.info(list.toString());The list remains unchanged.
4) Modifying element attributes with foreach
While you cannot replace the element itself, you can change its internal state because the loop variable still references the original object:
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
list = new ArrayList<>();
list.add(s1);
list.add(s2);
System.out.println(s1.getName()); // huge
System.out.println(s2.getName()); // xiaoyao
for (Student stu : list) {
stu.setName("jingtian");
}
System.out.println(s1.getName()); // jingtian
System.out.println(s2.getName()); // jingtianThe names are updated because the objects themselves are mutated.
Summary
Both for and foreach can iterate arrays and collections, but for offers higher flexibility for complex operations such as element removal or replacement. foreach cannot delete or replace collection elements directly and will throw a ConcurrentModificationException when a removal is attempted without using the iterator’s remove() . However, both loops can modify the internal state of objects contained in the collection.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
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.