foreach循环里list.remove倒数第二个元素不会报ConcurrentModificationException异常

本文深入探讨了在Java中ArrayList的remove方法与Iterator的remove方法的区别,特别是在并发操作和迭代过程中可能出现的ConcurrentModificationException异常。强调了使用Iterator的remove方法在遍历和删除元素时的线程安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键就是:foreach的底层就是迭代器,迭代器循环会依次调hasNext()和iterator.next()

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开发手册》相关内容:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值