Iterating over a collection using a for-each
loop in Java relies on iterators.
An iterator is an object that allows you to traverse a collection of elements, such as a list or a dictionary. Iterators are used in
for-each
loops to iterate over the elements of a collection one at a time.
It is important to note that iterators are designed to be read-only. Modifying a collection while iterating over it can cause unexpected behavior,
as the iterator may skip over or repeat elements. Therefore, it is important to avoid modifying a collection while iterating over it to ensure that
your code behaves as expected.
Most JDK collection implementations don’t support such modification and may throw a ConcurrentModificationException
. Even if no such
exception is thrown, attempting to modify a collection during iteration could be the source of incorrect or unspecified behaviors in the code.
If you still want to modify the collection, it is best to refactor the code and use a second collection (e.g by using streams and filter
operations).
Code examples
Noncompliant code example
public static void foo(List<String> lst) {
for (String element : lst) {
if (element.startsWith("x")) {
lst.remove(element); // Noncompliant: lst size has been modified by "remove" call while it's iterated.
}
}
}
Compliant solution
public static void foo(List<String> lst) {
List<String> toRemove = new ArrayList<>();
for (String element : lst) {
if (element.startsWith("x")) {
toRemove.add(element);
}
}
lst.removeAll(toRemove);
}