为了账号安全,请及时绑定邮箱和手机立即绑定

迭代时删除离开元素并且不抛出并发 E

迭代时删除离开元素并且不抛出并发 E

慕的地8271018 2023-04-19 17:01:14
我遇到了这段代码,它在迭代时从列表中删除了项目,但它并没有抛出并发异常并在列表中留下了一些项目。这是为什么?例子:。public class Application {    public static void main(String[] args) {        List<Integer> integerList = new ArrayList<Integer>();        integerList.add(1);        integerList.add(2);        for (Integer integer : integerList) {            removeInteger(integerList, integer);        }        System.out.println(integerList.toString()); // prints [2] as it was not removed (while it should be)    }    private static void removeInteger(List<Integer> integerList, Integer integer) {        for (Integer integer1 : integerList) {            if (integer.equals(integer1)) {                int index = integerList.indexOf(integer);                if (index >= 0) {                    integerList.remove(index);                }            }        }    }}如果我将removeInteger方法更改为 useIterator而不是main我传递的副本,则integerList一切都按预期工作。
查看完整描述

1 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

首先,如果您向列表中添加更多元素,它仍然会失败并显示ConcurrentModificationException.

由于发布的示例没有失败,我们必须看看内部发生了什么。

如果您进行调试,您会在发布的示例中看到,两个循环仅迭代一次。删除内部循环(方法)中的元素removeInteger会耗尽两个迭代器。由于没有进一步的交互,因此不会导致错误。“仅”修改后的调用Iterator#next可能导致 ConcurrentModificationException。

是的,但为什么它会耗尽它们呢?

查看源代码ArrayList#Itr我们可以看到

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

只检查一个名为 的变量size。此变量size是 的属性ArrayList。当remove被调用时,该变量递减。因此,下次hasNext调用时,迭代器假定不再有新元素。

旁注:cursor指向列表中的下一个元素。


查看完整回答
反对 回复 2023-04-19
  • 1 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信