代码之家  ›  专栏  ›  技术社区  ›  Arpit Agrawal

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

  •  -3
  • Arpit Agrawal  · 技术社区  · 7 年前
    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 回复  |  直到 7 年前
        1
  •  1
  •   theo    7 年前

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

        2
  •  1
  •   Andy Turner    7 年前

    实施 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() 在最后的第二个元素中,减少 大小 ,但不要改变 光标 先前 cursor == size - 1 ; 现在 cursor == size .

    值得注意的是 hasNext() 不会调用 checkForComodification() 方法因此,while循环对 hasNext() ,发现它是错误的,然后停止。(使用for each循环可以观察到相同的行为)。

    这仅仅是实现 ArrayList ,而不是你应该依赖的东西。