java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java遍历集合并发修改异常

Java中遍历集合的并发修改异常解决方案实例代码

作者:蓝桉cyq

当你遍历集合的同时,又往集合中添加或者删除元素,就可能报并发修改异常,下面这篇文章主要给大家介绍了关于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遍历集合并发修改异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文