Java中遍历集合的并发修改异常解决方案实例代码
遍历集合的删除元素的问题
问题引出:
当我们遍历集合从中找出某一批元素并删除的时候, 可能出现一种并发修改异常问题。
哪些变量会存在这个问题?
迭代器遍历集合且直接用集合删除元素的时候可能出现, 例如下面代码就会报错。
public static void main(String[] args) { Collection<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); // 删除全部aaa元素 Iterator<String> ite = list.iterator(); while (ite.hasNext()) { String item = ite.next(); if ("aaa".equals(item)) { list.remove("aaa"); } } }
增强for循环遍历集合且直接用集合删除元素的时候可能出现, 例如下面代码同样会报错。
public static void main(String[] args) { Collection<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); for (String item : list) { if ("aaa".equals(item)) { list.remove("aaa"); } } }
Lambda方法遍历同样会出现一样的bug
public static void main(String[] args) { Collection<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); list.forEach(s -> { if ("aaa".equals(s)) { list.remove("aaa"); } }); }
使用for循环, 不会报错, 但是删除数据会出现问题, 例如下面代码中会漏删aaa
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("aaa"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); for (int i = 0; i < list.size(); i++) { String item = list.get(i); if ("aaa".equals(item)) { list.remove("aaa"); } } System.out.println(list); // [ccc, ddd, aaa] }
解决方案:
迭代器的解决方法: 迭代器遍历集合但是用迭代器自己的删除方法操作可以解决。
public static void main(String[] args) { Collection<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); // 删除全部aaa元素 Iterator<String> ite = list.iterator(); while (ite.hasNext()) { String item = ite.next(); if ("aaa".equals(item)) { // shiy 迭代器删除方法, 删除当前所在元素 ite.remove(); } } System.out.println(list); // [bbb, ccc, ddd] }
for循环的解决方法一: 从后往前删
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("aaa"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); for (int i = list.size() - 1; i >= 0; i--) { String item = list.get(i); if ("aaa".equals(item)) { list.remove("aaa"); } } System.out.println(list); // [ccc, ddd] }
for循环的解决方法二: 删除完元素让 i 减1,
i--
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("aaa"); list.add("ccc"); list.add("aaa"); list.add("ddd"); list.add("aaa"); for (int i = 0; i < list.size(); i++) { String item = list.get(i); if ("aaa".equals(item)) { list.remove("aaa"); // 删除了元素i-- i--; } } System.out.println(list); // [ccc, ddd] }
总结
到此这篇关于Java中遍历集合的并发修改异常解决的文章就介绍到这了,更多相关Java遍历集合并发修改异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
MybatisPlus为何可以不用@MapperScan详解
这篇文章主要给大家介绍了关于MybatisPlus为何可以不用@MapperScan的相关资料,文中通过图文介绍的非常详细,对大家学习或者使用MybatisPlus具有一定的参考学习价值,需要的朋友可以参考下2023-04-04
最新评论