为什么从arraylist remove方法中删除倒数第二个元素不会引发ConcurrentModificationException?

时间:2019-01-07 09:59:28

标签: java

List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
l.add("4");
Iterator<String> itr = l.iterator();
while (itr.hasNext()) {
    String str = itr.next();
    if (str.equals("3")) {
        l.remove(str);
    }
}

为什么上面的代码不抛出ConcurrentModificationException

2 个答案:

答案 0 :(得分:1)

因为删除元素的方式(作为removeIf实现的一部分)是通过Iterator对象完成的。

答案 1 :(得分:1)

ArrayList.Itr's hasNext() method is的实现:

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    // ...

    public boolean hasNext() {
        return cursor != size;
    }

其中cursor是迭代器的实例字段,而size是列表的大小。

因此,如果在倒数第二个元素上调用remove(),则会减小size,但不要更改cursor。以前是cursor == size - 1;现在,cursor == size

重要的是,此hasNext()不会调用checkForComodification()方法。这样,while循环对hasNext()求值,发现它为假,然后停止。 (您可以通过for-each循环观察到相同的行为。)

这仅仅是ArrayList实现的一个怪癖,而不是您应该依赖的东西。