gpt4 book ai didi

java - 为什么我在此示例中没有收到 java.util.ConcurrentModificationException?

转载 作者:太空宇宙 更新时间:2023-11-04 10:44:03 25 4
gpt4 key购买 nike

注意:我知道 Iterator#remove() 方法。

在下面的代码示例中,我不明白为什么 main 方法中的 List.remove 会抛出 ConcurrentModificationException,但 remove 方法中不会

public class RemoveListElementDemo {    
private static final List<Integer> integerList;

static {
integerList = new ArrayList<Integer>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
}

public static void remove(Integer toRemove) {
for(Integer integer : integerList) {
if(integer.equals(toRemove)) {
integerList.remove(integer);
}
}
}

public static void main(String... args) {
remove(Integer.valueOf(2));

Integer toRemove = Integer.valueOf(3);
for(Integer integer : integerList) {
if(integer.equals(toRemove)) {
integerList.remove(integer);
}
}
}
}

最佳答案

原因如下:正如 Javadoc 中所述:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

此检查是在迭代器的 next() 方法中完成的(如堆栈跟踪所示)。但只有当 hasNext() 传递 true 时,我们才会到达 next() 方法,这就是 foreach 调用的方法来检查是否满足边界。在您的删除方法中,当 hasNext() 检查是否需要返回另一个元素时,它会发现它返回了两个元素,现在删除一个元素后列表只包含两个元素。所以一切都很顺利,我们已经完成了迭代。不会进行并发修改检查,因为这是在 next() 方法中完成的,而该方法从未被调用。

接下来我们进入第二个循环。删除第二个数字后,hasNext 方法将再次检查是否可以返回更多值。它已经返回了两个值,但列表现在只包含一个。但这里的代码是:

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

1 != 2,因此我们继续使用 next() 方法,该方法现在意识到有人弄乱了列表并引发异常。

希望能解答您的疑问。

摘要

List.remove() 从列表中删除倒数第二个元素时不会抛出 ConcurrentModificationException

关于java - 为什么我在此示例中没有收到 java.util.ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615153/

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