繁体   English   中英

Java中允许remove()方法工作的Iteration的内部实现是什么?

[英]What is internal implementation of Iteration in java that allows remove() method to work?

由foreach循环迭代时,列表中的任何项目都无法删除。 但是,当我们通过迭代器对其进行迭代时,可以通过迭代器的remove()方法将其删除。

我了解故障快速和故障安全的概念,并且也知道Iterator是java为我们提供删除选项的方式。 但是我想知道java提供的Iterator的remove()方法的内部实现,这有助于完成此操作。

import java.util.*;
public class RemoveCollection {
public static void main(String[] args) {
    List<String> ls = new ArrayList<String>();
    ls.add("apple");
    ls.add("orange");
    ls.add("kiwi");

    Iterator it = ls.iterator();
    while(it.hasNext()) {
        it.next();
        //works fine and the item is removed from list
        it.remove();
    }

    ls.add("apple");
    ls.add("orange");
    ls.add("kiwi");
    while(it.hasNext()) {
        it.next();
        //throws concurrentmodification exception
        ls.remove();
    }
  }
}

您可以通过简单地查看JDK随附的ArrayList的源代码来了解这一点:

ArrayList具有此字段(从AbstractList继承):

protected transient int modCount = 0;

每次对列表进行操作时,它都会递增。 例如, ArrayList.remove()具有以下指令:

modCount++;

ArrayList的迭代器具有以下代码:

int expectedModCount = modCount;

public E next() {
   checkForComodification();
   [...]
}

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

因此,如您所见,在迭代时,它将检查列表的modCount是否未被修改。

remove()方法执行以下操作:

ArrayList.this.remove(lastRet);
[...];
expectedModCount = modCount;

因此,它将元素从列表中删除,然后更新其expectedModCount ,以便在调用checkForComodification()时使用迭代器完成的下一个操作不会失败。

要理解的关键是方法iterator()返回一个可以访问列表内部结构的对象。 不仅可以迭代其元素,还可以检查在使用迭代器完成的两次操作之间是否已修改该列表。

List<E>扩展AbstractList<E> 这个抽象类包含方法iterator() ,该方法返回一个新的Iterator(第287行)。 您可以看到源代码

public Iterator<E> iterator() {
    return new Itr();
}

下面的几行(第330行)是private class Itr implements Iterator<E> ,它private class Itr implements Iterator<E> ,它定义并实现了第368行的remove()方法:

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        AbstractList.this.remove(lastRet);
        if (lastRet < cursor)
            cursor--;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException e) {
        throw new ConcurrentModificationException();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM