Java中遍历集合的并发修改异常解决方案实例代码
蓝桉cyq 人气:0遍历集合的删除元素的问题
问题引出:
当我们遍历集合从中找出某一批元素并删除的时候, 可能出现一种并发修改异常问题。
哪些变量会存在这个问题?
迭代器遍历集合且直接用集合删除元素的时候可能出现, 例如下面代码就会报错。
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] }
总结
加载全部内容