List集合循环remove/add时报错ConcurrentModificationException

本文详细解释了Java中List集合在循环中执行remove或add操作时抛出ConcurrentModificationException的原因,涉及ArrayList的modCount和expectedModCount变量。分析了fail-fast机制和CopyOnWriteArrayList的工作原理,提供了解决并发修改异常的多种方案,包括使用CopyOnWriteArrayList、迭代器配合while循环、for循环、Java 8的filter方法以及使用fail-safe集合类。
摘要由CSDN通过智能技术生成

在这里插入图片描述
其实关于这个问题,在阿里巴巴Java开发手册中有规定:
在这里插入图片描述
WHY ?

查看源码之后才知道是因为
在这里插入图片描述

那么modCount和expectedModCount是什么呢?
在这里插入图片描述

modCount是ArrayList中的一个成员变量。它表示该集合实际被修改的次数。
expectedModCount 是 ArrayList中的一个内部类——Itr中的成员变量。

expectedModCount表示这个迭代器预期该集合被修改的次数。其值随着Itr被创建而初始化。只有通过迭代器对集合进行操作,该值才会改变。

那么,接着我们看下userNames.remove(userName);方法里面做了什么事情,为什么会导致expectedModCount和modCount的值不一样。

通过翻阅代码,我们也可以发现,remove方法核心逻辑如下:
在这里插入图片描述
可以看到,remove方法只修改了modCount,并没有对expectedModCount做任何操作。

之所以会抛出CMException异常,是因为我们的代码中使用了增强for循环,而在增强for循环中,集合遍历是通过iterator进行的,但是元素的add/remove却是直接使用的集合类自己的方法。这就导致iterator在遍历的时候,会发现有一个元素在自己不知不觉的情况下就被删除/添加了,就会抛出一个异常,用来提示用户,可能发生

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值