gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:04:47 25 4
gpt4 key购买 nike

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

我理解fail-fast和fail-safe的概念,并且也意识到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,以便迭代器完成的下一个操作在调用 checkForCommodification() 时不会失败.

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

关于java - java中允许remove()方法工作的Iteration的内部实现是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51570266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com