使用集合删除方法时,Java并发修改异常未到来

KIt*_*tis 2 java collections arraylist concurrentmodification

我在许多地方看到它说在迭代时从ArrayList中删除一个元素时,我应该使用iterator remove方法而不是collections remove方法来避免并发修改异常.

但是,下面的代码可以正常使用Java 1.8 Collection remove而不会给出并发修改异常.你可以看到我在这里没有使用迭代器来删除对象.

List<MyObject> list = new ArrayList<MyObject>();
list.add(new MyObject());
list.add(new MyObject());
list.add(new MyObject());

for (int i=0; i<list.size(); i++) {
        list.remove(i);     
}
Run Code Online (Sandbox Code Playgroud)

Jir*_*sek 6

您的示例不会抛出异常.但它也不会从列表中删除所有元素.

真正做到了什么

  • 在第一次迭代时,它删除索引0; 列表中仍有2个元素
  • 在第二次迭代中,它删除索引1(实际上是最后一个元素); 剩下1个元素
  • 第三次迭代不会发生,因为那时list.size()是1,小于2

起初,我认为它会抛出一个IndexOutOfBoundsException,但是在list.size()每次迭代开始时评估的事实确保它不会.

为什么不扔 ConcurrentModificationException

因为你没有使用迭代器.

如果使用迭代器迭代列表,然后修改(例如从列表中删除),然后尝试推进迭代器,则抛出此异常,如下所示:

Iterator<MyObject> it = list.iterator();
while (it.hasNext()) {
    list.remove(it.next());
}
Run Code Online (Sandbox Code Playgroud)

正如@Ferrybig指出的那样,即使在这种情况下,迭代器也可能实际上不会抛出异常 - 请参阅相关问题.