当前位置: 首页 > news >正文

ConcurrentModificationException并发修改异常

ConcurrentModificationException并发修改异常

原因分析

可以通过遍历索引也可以通过迭代器进行遍历。在我们使用迭代器进行遍历集合的时候,会获取到当前集合的迭代对象。在里面有封装了迭代器的remove方法与集合自带的remove方法,如果我们调用迭代器对象的remove方法是没问题的,但是当我们调用集合自带的remove方法时,就会产生ConcurrentModificationException 并发修改异常。也就是说,当我们通过非迭代器进行遍历集合的时候,是不允许集合本身在结构上发生变化的。
增删操作会导致 预期数量和 计数器的数量不一致,就会导致并发修改异常

解决方式

1,ListIterator列表迭代器(list特有的迭代器),将添加、删除元素交给迭代器去做,而非集合

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");ListIterator<String> stringListIterator = list.listIterator();
while (stringListIterator.hasNext()) {String element = stringListIterator.next();if(StringUtils.equals(element,"C")) {// 在遍历时向列表中添加元素stringListIterator.add("D");}
}
System.out.println(list);//[A, B, B, C, D]

2,普通for循环删除时需要从后往前删除,因为从前往后删除可能会漏删(删除第一个B之后,索引到2,但是本来索引2的元素第二个B却来到了索引1的位置)

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");for (int i = list.size()-1; i >= 0; i--) {if(StringUtils.equals(list.get(i),"B")) {list.remove("B");}
}System.out.println(list);

3,使用CopyOnWriteArrayList集合,底层解决并发修改异常,就可以使用集合的增删方法在遍历时操作

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList(list);
for (String ele :copyOnWriteArrayList){if(StringUtils.equals(ele,"C")) {// 在遍历时向列表中添加元素copyOnWriteArrayList.add("D");}
}System.out.println(copyOnWriteArrayList);//[A, B, B, C, D]

4,当遍历时需要删除元素时,可以使用普通迭代器,普通迭代器没有新增方法

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");
//普通迭代器,只能删除,没有add
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){String next = iterator.next();if(StringUtils.equals(next,"B")) {iterator.remove();//迭代器删除第一个B,然后hasNext拉到下一个B,迭代器再删除一次}
}
System.out.println(list);//[A, C]

5,增强for循环底层采用迭代器,遍历时删除(新增)只能用集合的删除(新增)方法,还会报并发修改异常

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");for (String element : list) {//Caused by: java.util.ConcurrentModificationException: nullif(StringUtils.equals(element,"B")) {list.add("B");}
}
System.out.println(list);//[A, B, B, C, D]
http://www.lryc.cn/news/309284.html

相关文章:

  • 小程序事件处理
  • 蓝桥杯-单片机组基础6——定时计数器与外部中断混合使用(附小蜜蜂课程代码)
  • 交友社交软件开发-php交友聊天系统-
  • vue2 开发记录
  • QML中表格中数据获取
  • 【mysql 数据库事务】开启事务操作数据库,写入失败后,不回滚,会有问题么? 这里隐藏着大坑,复试,面试时可以镇住面试老师!!!!
  • Go语言的100个错误使用场景(55-60)|并发基础
  • 钉钉机器人发送折线图卡片 工具类代码
  • 基于springboot的大型商场应急预案管理系统论文
  • 强化学习嵌入Transformer(代码实践)
  • 决定西弗吉尼亚州地区版图的关键历史事件
  • LeetCode_22_中等_括号生成
  • Verilog(未完待续)
  • 【Linux实践室】Linux初体验
  • Flutter中高级JSON处理:使用json_serializable进行深入定制
  • 华为OD技术面试案例4-2024年
  • 【TestNG】(4) 重试机制与监听器的使用
  • “智农”-高标准农田
  • 利用 lxml 库的XPath()方法在网页中快速查找元素
  • nginx---------------重写功能 防盗链 反向代理 (五)
  • unity shaderGraph实例-物体线框显示
  • 分类问题经典算法 | 二分类问题 | Logistic回归:公式推导
  • redis实现分布式全局唯一id
  • Sora引发安全新挑战
  • Android 14.0 Launcher3定制化之桌面分页横线改成圆点显示功能实现
  • SemiDrive E3 MCAL 开发系列(3)– Wdg 模块的使用
  • AI推荐算法的演进之路
  • Tomcat安装,配置文件、组件
  • 精读《React Hooks 最佳实践》
  • varFormatter 数据格式化库 以性能优先的 快速的 内存对象格式转换