为什么会发生以下情况?两者都不行吗?

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);
    }
}

是因为add()添加到集合Items中,但是addAll()创建了一个新集合,从而将Items修改为List的其他实例吗?

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

最佳答案

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

检查the implementation of ArrayList表明,调用addaddAll应该成功在下一次循环迭代时引发ConcurrentModificationException。它对add没有这样做的事实意味着,或者针对您所拥有的特定Java版本,ArrayList类中存在一个难以理解的错误。或者otherItems为空,因此在第二种情况下,您实际上根本没有调用add

我确定otherItems必须为空,因为如果按照您希望的方式添加到Items列表“工作”,那么它将在循环中每次增长,导致其无限循环,直到死于OutOfMemoryError为止。

09-11 18:51