The ForEach loop will not loop directly on your collection. It uses the iterator of your collection. You can see the iterator in the implementation of your collections.
From Arraylist Source Code
735
736 public Iterator<E> More ...iterator() {
737 return new Itr();
738 }
An optimized version of AbstractList.Itr
742
743 private class More ...Itr implements Iterator<E> {
744 int cursor;
And your foreach loop is equal
for(Iterator<Integer> i = targets.iterator(); i.hasNext(); ) {
Integer element = i.next();
//To do
}
So, if you perform any operation here, and at the same time as changing the collection, the iterator under the hood gets confused and throws an exception.
From JLS
List<? extends Integer> l = ...
for (float i : l) ...
will be translated into:
for (Iterator<Integer>
float
...