ForEach loop won't loop directly on your collection. It uses the iterator of your collection behind. you can see the iterator in your collections implementation.
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; // index of next element to return
And your foreach loop equals to
for(Iterator<Integer> i = targets.iterator(); i.hasNext(); ) {
Integer element = i.next();
//To do
}
So if you doing any operation here, and the same time you modifying the collection, iterator under the hood got confuse and throws exception.
From JLS
List<? extends Integer> l = ...
for (float i : l) ...
will be translated to:
for (Iterator<Integer> #i = l.iterator(); #i.hasNext(); ) {
float #i0 = (Integer)#i.next();
...