ConcurrentModificationException 未一致抛出

Zex*_*ong 5 java iterator

在本例中使用list.remove((Object)93)Causes a :ConcurrentModificationException

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(14);
list.add(2);
list.add(44);
list.add(41);
list.add(93);
list.add(20);

for(Iterator<Integer> it = list.iterator();it.hasNext();) {
    list.remove((Object)93);
    it.next();
}
System.out.println(list);
Run Code Online (Sandbox Code Playgroud)

但是,当我包含list.remove((Object)93)if 语句时,它不会导致任何错误。为什么?

for(Iterator<Integer> it = list.iterator();it.hasNext();) {
    int num = it.next();
    if(num == 93) {
        list.remove((Object)93);
    }
}
System.out.println(list);
Run Code Online (Sandbox Code Playgroud)

mic*_*alk 5

在第一个示例中,您在第一次迭代时得到ConcurrentModificationException,这是预期的,因为您在使用迭代器迭代时修改了列表。

93在第二个示例中,从您的中删除后,ArrayList甚至it.next()不会被调用,因为hasNext将返回 false - 请参阅以下实现ArrayList.Itr::hasNext:

public boolean hasNext() {
    return this.cursor != ArrayList.this.size;
}
Run Code Online (Sandbox Code Playgroud)

它只检查ArrayList大小是否与光标不同。在您的示例中,该93元素被放置在最后一个位置。删除93元素后,大小将减少一,因此it.next()将计算为false并且it.next不会被调用,并且不会引发异常。

这是一个巧合,您放置93在最后一个位置的前一个位置,因此您没有收到异常。ArrayList尝试在after中添加另一个值93,ConcurrentModificationException将会像第一个示例一样被抛出。