【问题标题】:ConcurrentModificationException not thrown consistentlyConcurrentModificationException 未一致抛出
【发布时间】:2019-12-16 15:10:03
【问题描述】:

在本例中使用list.remove((Object)93) 会导致ConcurrentModificationException

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(14);
list.add(2);
list.add(44);
list.add(41);
list.add(93);
list.add(20);

for(Iterator<Integer> it = list.iterator();it.hasNext();) {
    list.remove((Object)93);
    it.next();
}
System.out.println(list);

但是,当我将 list.remove((Object)93) 包装在 if 语句中时,它不会导致任何错误。为什么?

for(Iterator<Integer> it = list.iterator();it.hasNext();) {
    int num = it.next();
    if(num == 93) {
        list.remove((Object)93);
    }
}
System.out.println(list);

【问题讨论】:

  • 我不相信这是重复的,至少不是链接问题。这个问题特别讨论了在迭代列表时使用list.remove() 删除项目,而不是it.remove()

标签: java iterator


【解决方案1】:

在第一个示例中,您在第一次迭代时获得了 ConcurrentModificationException,这是预期的,因为您在使用迭代器进行迭代时修改了列表。

在从 ArrayList 中删除 93 之后的第二个示例中,it.next() 甚至不会被调用,因为 hasNext 将返回 false - 请参阅 ArrayList.Itr::hasNext 的实现:

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

它只检查ArrayList 的大小是否与光标不同。在您的示例中,93 元素放置在最后一个位置。删除 93 元素后,大小将减少 1,因此 it.next() 将评估为 false 并且不会调用 it.next 并且不会引发异常。

这是一个巧合,您将93 放在倒数第二位,因此您没有收到异常。尝试在93ConcurrentModificationException 之后向ArrayList 添加另一个值,就像在第一个示例中一样。

【讨论】:

    猜你喜欢
    • 2013-02-12
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2017-10-18
    • 1970-01-01
    • 2023-02-01
    相关资源
    最近更新 更多