循环List删除元素抛ConcurrentModificationException异常原因分析

使用for(Object obj:list)进行循环ArrayList时,如果循环删除list中的元素则会抛出 ConcurrentModificationException异常,如下图:


通过分析错误堆栈我们可以发现使用 for(Object obj:list) 进行循环时,实际上是调用List迭代器(iterator)的next方法进行循环(AbstractList类中的Itr内部类的next方法):


这时,next方法的第一行会对ArryList做校验,如果校验不通过,则抛出 ConcurrentModificationException异常

checkForComodification方法:

该方法实际上是对modCount和expectedModCount变量进行比较,如果不同,则抛出异常。
这里涉及到两个变量:
modCount:AbstractList类成员变量。记录List结构变化的次数,每次改变list结构时(add,remove,trimToSize等)都会加1

expectedModCount:Itr(AbstractList类的迭代器)类成员变量,初始时和modCount相等:

每次调用 迭代器的remove方法会对expectedModCount重新赋值modCount相同:

了解这两个变量后我们就会发现,for循环中调用的remove方法是ArrayList的remove方法会对modCount变量加1,但expectedModCount变量并未改变。这样,在第二次循环时调用迭代器的next方法就会校验出错。

所以,如果需要对list进行循环删除时要使用迭代器,并调用迭代器的remove方法。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值