为什么java for循环不要在foreach循环里进行元素的remove/add操作

首先这涉及多线程操作,Iterator是不支持多线程操作的List类会在内部维护一个modCount的变量,用来记录修改次数

每生成一个IteratorIterator就会记录该modCount,每次调用next()方法就会将该记录与外部类List的modCount进荇对比发现不相等就会抛出多线程编辑异常。

为什么这么做呢我的理解是你创建了一个迭代器,该迭代器和要遍历的集合的内容是紧耦合的意思就是这个迭代器对应的集合内容就是当前的内容,我肯定不会希望在我冒泡排序的时候还有线程在向我的集合里插入数据對吧?所以java for循环用了这种简单的处理机制来禁止遍历时修改集合

至于为什么删除“1”就可以呢,原因在于foreach和迭代器的hasNext()方法foreach这个语法糖,实际上就是

cursor是用于标记迭代器位置的变量该变量由0开始,每次调用next执行+1操作于是:
你的代码在执行删除“1”后,size=1cursor=1,此时hasNext()返回false结束循环,因此你的迭代器并没有调用next查找第二个元素也就无从检测modCount了,因此也不会出现多线程修改异常
但当你删除“2”时迭代器调用叻两次next,此时size=1cursor=2,hasNext()返回true于是迭代器傻乎乎的就又去调用了一次next(),因此也引发了modCount不相等抛出多线程修改的异常。

当你的集合有三个元素嘚时候你就会神奇的发现,删除“1”是会抛出异常的但删除“2”就没有问题了,究其原因和上面的程序执行顺序是一致的。

确认一键查看最优答案

本功能為VIP专享,开通VIP获取答案速率将提升10倍哦!

可是会出错改用for吗??


帮忙看看我也是循环删除的问题,有点不明白


帮忙看看我也是循環删除的问题,有点不明白

不行因为你删的时候表的行数是动态的,可以考虑从后面删


看到以上回复我也学习了,谢谢大家!!

Foreach是只讀的也可以用

没考虑过对collection类型的对象进行遍历操作时for 和foreach的区别,只是觉得使用foreach会更方便一些今天使用foreach循环来操作删除某个collection的元素,出现異常:查询集合已修改;可能无法执行枚举操作。这个是使用foreach的典型的问题foreach是取只读的,在取的时候数据不能变(包括修改删除,添加等)要避免这个问题,就应该使用for循环


匿名用户不能发表回复!

我要回帖

更多关于 java for循环 的文章

 

随机推荐