FreakyDan FreakyDan - 1 year ago 51
Java Question

ConcurrentModificationException: .add() vs .addAll()

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

// 2. .add()
//Doesn't cause exceptions
for( String otherId : otherItems ) {

Is it because
adds to the collection Items, but
creates a new collection thus modifying Items to be a different instance of List?

are of concrete type

Answer Source

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.