Why does the following occur? Shouldn't both work?
List<String> items = data;
for( String id : items ) {
List<String> otherItems = otherData;
// 1. addAll()
//Causes ConcurrentModificationException
items.addAll(otherItems);
// 2. .add()
//Doesn't cause exceptions
for( String otherId : otherItems ) {
items.add(otherId);
}
}
Is it because add()
adds to the collection Items, but addAll()
creates a new collection thus modifying Items to be a different instance of List?
Edit
items
and otherItems
are of concrete type ArrayList<String>
.
Neither operation is proper, since it modifies the collection while iterating it.
Examining the implementation of ArrayList shows that calling either add
or addAll
should successfully throw the ConcurrentModificationException on the next loop iteration. The fact that it isn't doing that for add
means that either there is an obscure bug in the ArrayList class for the particular version of Java you have; or (more likely) otherItems
is empty, so in the second case, you aren't actually calling add
at all.
I'm sure otherItems
must be empty, because if adding to the Items
list "worked" in the way you want, then it would grow every time around the loop, causing it to loop indefinitely until dying with an OutOfMemoryError.