foreach循环remove倒数第二个不会报ConcurrentModificationException异常

问题原因remove倒数第二个后,ArrayList集合私有属性size=size -1。
接着迭代下一次循环时先判断 hasNext,
 public boolean hasNext() {
     return cursor != size;
}
此时游标cursor == size 
hasNext返回false 循环结束。会丢失最后一个元素的遍历。

 


问题的关键点是用的是集合的remove方法,而不是用的是迭代器的remove方法。

正如:用的不是同一厂商的东西,无法保证整体质量效果。

1.迭代器的remove方法

在集合迭代的过程中,为了判断线程的安全,迭代器的方法都会判断集合实际修改的次数与预期的修改次数。
迭代器的remove方法删除元素时会立即修改集合实际修改的次数与预期的修改次数。如下图 红框

附:remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

 

2.ArrayList的remove方法

增加List的修改次数。

 

使用ArrayList的remove方法后,集合还未遍历完,继续下次迭代,调用迭代器的next方法取下一个集合元素。

3.迭代器next方法:

next 中checkForComodification会判断预期元素修改的次数是否等于集合的实际的元素修改次数,由于使用的ArrayList的remove方法。造成modCount != expectedModCoun抛出ConcurrentModificationException异常
 

 

写在最后:阿里巴巴java开发手册的一个强制规范:

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值