首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java中允许remove()方法工作的迭代的内部实现是什么?

java中允许remove()方法工作的迭代的内部实现是什么?
EN

Stack Overflow用户
提问于 2018-07-28 18:08:29
回答 2查看 502关注 0票数 1

当被foreach循环迭代时,列表中的任何项都不能被移除。但是,当我们通过迭代器迭代它时,可以通过迭代器的remove()方法将其移除。

我理解fail-fast和fail-safe的概念,也知道Iterator是java为我们提供删除选项的方式。但是我想知道java提供的Iterator的remove()方法的内部实现,它简化了这个操作。

代码语言:javascript
复制
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();
    }
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-28 18:18:31

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

ArrayList有这个字段(继承自AbstractList):

代码语言:javascript
复制
protected transient int modCount = 0;

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

代码语言:javascript
复制
modCount++;

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

代码语言:javascript
复制
int expectedModCount = modCount;

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

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

因此,正如您所看到的,当它迭代时,它会检查列表的modCount是否未被修改。

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

代码语言:javascript
复制
ArrayList.this.remove(lastRet);
[...];
expectedModCount = modCount;

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

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

票数 1
EN

Stack Overflow用户

发布于 2018-07-28 18:25:36

List扩展了AbstractList。这个抽象类包含方法iterator(),它返回一个新的迭代器(第287行)。您可以看到source code

代码语言:javascript
复制
public Iterator<E> iterator() {
    return new Itr();
}

下面几行(在线330上)在线368上有定义并实现方法remove()private class Itr implements Iterator<E>的定义:

代码语言:javascript
复制
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();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51570266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档