ArrayList中移除数据报错

最近看到了一个线程安全的list ,位于

java.util.concurrent包下面CopyOnWriteArrayList,想起来很久之前使用ArrayList踩得坑,在此记录一下:

        List<String> list = new ArrayList();
        list.add("A");
        list.add("B");
        list.add("C");

        for (String str : list) {
            if ("A".equals(str)) {
                list.remove(str);
            }
        }

项目中我们可能有时候会用上面写法移除list中数据,但是运行就会发现报错,java.util.ConcurrentModificationException,

源码发现for each执行时会走如上代码,移除之后的size不等,便会报错,

要想正确移除数据可以用下面方法迭代器iterator

        List<String> list = new ArrayList();
        list.add("A");
        list.add("B");
        list.add("C");

        Iterator var = list.iterator();
        while (var.hasNext()) {
            String str = (String) var.next();
            if ("A".equals(str)) {
                var.remove();
            }
        }

后来看了一遍博客,发现CopyOnWriteArrayList也可以直接实现移除效果,而且不会报错:

        List<String> list = new CopyOnWriteArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        for (String str : list) {
            if ("A".equals(str)) {
                list.remove(str);
            }
        }

为什么不报错呢,源码发现每次执行for each循环执行时会拷贝一份新的数据,每次remove方法时都是操作的新数组,操作完成后再把旧的数组引用指向新的数据,再执行操作,故不会出错。

那CopyOnWriteArrayList还有哪些优点的,首先读写分离,故线程安全,比vector效果高 ,故后续项目中可以酌情使用其替代ArrayList。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页