Java集合并发修改异常问题(删除集合中多个元素)

前言:之前写过一篇博客,python列表删除多个下标,同样地,在Java集合中,需要删除多个元素时,也会遇到并发修改异常的问题,那如何进行处理呢?

目录

问题

原因

解决方法

其他方法-迭代器遍历

总结


问题

给定一个ArrayList列表,删除列表中包含"w"的元素

java 复制代码
package learn11;

import java.util.ArrayList;
import java.util.List;

public class ListLearn {
    public static void main(String[] args) {
        List<String> List = new ArrayList<>();
        List.add("learning");
        List.add("wyLearning");
        List.add("test");
        List.add("wy");
        List.add("wangying");
        List.add("wyy");

        for (int i = 0; i < List.size(); i++) {
            String s = List.get(i);
            if (s.contains("w")) {
                List.remove(s);
            }
        }
        System.out.println(List);
    }
}

可以看到,实际上元素并删干净,留下了"wangying"这个元素。

原因

debug一下,可以观察到,在删除了第一个包含"w"的元素后,数组的长度-1,但i的值没有发生变化,所以i跳过了索引为1的元素"test",也就是这个原因,同理,跳过了"wangying"这个元素。清楚了原理,我们就知道在每删除一个元素时,遍历的索引都-1,就可以解决这个问题了。

解决方法

java 复制代码
package learn11;

import java.util.ArrayList;
import java.util.List;

public class ListLearn {
    public static void main(String[] args) {
        List<String> List = new ArrayList<>();
        List.add("learning");
        List.add("wyLearning");
        List.add("test");
        List.add("wy");
        List.add("wangying");
        List.add("wyy");

        for (int i = 0; i < List.size(); i++) {
            String s = List.get(i);
            if (s.contains("w")) {
                List.remove(s);
                i--;
            }
        }
        System.out.println(List);
    }
}

可以看到结果,含有"w"元素的已经都删掉了。

debug一下,每次删除元素后,索引-1,删掉第一个元素后,继续去遍历,从索引为1的"test"继续往下执行。

其他方法-迭代器遍历

当然,遍历元素,还有其他方法,接下来看一下用迭代器遍历,如何处理?

先来看下用普通方法,会有什么报错。

java 复制代码
package learn11;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListLearn {
    public static void main(String[] args) {
        List<String> List = new ArrayList<>();
        List.add("learning");
        List.add("wyLearning");
        List.add("test");
        List.add("wy");
        List.add("wangying");
        List.add("wyy");

        Iterator<String> it = List.iterator();
        while (it.hasNext()) {
            String name = it.next();
            if(name.contains("w")) {
                List.remove(name);
            }
        }
        System.out.println(List);
    }
}

抛出并发修改异常的错误:ConcurrentModificationException

实际上, 迭代器本身提供了删除的方法,使用迭代器提供的remove方法即可。

java 复制代码
package learn11;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListLearn {
    public static void main(String[] args) {
        List<String> List = new ArrayList<>();
        List.add("learning");
        List.add("wyLearning");
        List.add("test");
        List.add("wy");
        List.add("wangying");
        List.add("wyy");

        Iterator<String> it = List.iterator();
        while (it.hasNext()) {
            String name = it.next();
            if(name.contains("w")) {
                it.remove();
            }
        }
        System.out.println(List);
    }
}

总结

无论是在Java还是Python中,在一个容器里删除多个元素时,都要注意下标改变的问题。遇到并发修改异常的报错,要清除哪里除了问题,如果去解决此类问题。

相关推荐
Never_Satisfied37 分钟前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
80530单词突击赢1 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
3GPP仿真实验室1 小时前
【Matlab源码】6G候选波形:OFDM-IM 增强仿真平台 DM、CI
开发语言·matlab·ci/cd
devmoon1 小时前
在 Polkadot 上部署独立区块链Paseo 测试网实战部署指南
开发语言·安全·区块链·polkadot·erc-20·测试网·独立链
lili-felicity1 小时前
CANN流水线并行推理与资源调度优化
开发语言·人工智能
爬山算法1 小时前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
沐知全栈开发1 小时前
CSS3 边框:全面解析与实战技巧
开发语言
island13141 小时前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构 Stream 调度机制
c语言·开发语言·神经网络
云姜.1 小时前
线程和进程的关系
java·linux·jvm
是码龙不是码农1 小时前
支付防重复下单|5 种幂等性设计方案(从初级到架构级)
java·架构·幂等性