ConcurrentModificationException:.add()vs .addAll()

Fre*_*Dan 3 java foreach concurrentmodification

为什么会发生以下情况?两者都不应该有效吗?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

是因为add()添加了集合Items,还是addAll()创建了一个新的集合,从而将Items修改为List的另一个实例?

编辑 itemsotherItems具体类型ArrayList<String>.

Boa*_*ann 6

这两种操作都不正确,因为它在迭代时修改了集合.

检查ArrayList的实现表明,在下一个循环迭代中调用add或者addAll应该成功抛出ConcurrentModificationException.它没有这样做的事实add意味着,对于您拥有的特定Java版本,ArrayList类中存在一个模糊的错误; 或者(更有可能)otherItems是空的,所以在第二种情况下,你实际上并没有打电话add.

我肯定otherItems必须是空的,因为如果Items按照你想要的方式添加到列表"工作",那么它每次都会在循环中增长,导致它无限循环,直到死于OutOfMemoryError.