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


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

    目录

    问题

    原因

    解决方法

    其他方法-迭代器遍历

    总结


    问题

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

    1. package learn11;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. public class ListLearn {
    5. public static void main(String[] args) {
    6. List List = new ArrayList<>();
    7. List.add("learning");
    8. List.add("wyLearning");
    9. List.add("test");
    10. List.add("wy");
    11. List.add("wangying");
    12. List.add("wyy");
    13. for (int i = 0; i < List.size(); i++) {
    14. String s = List.get(i);
    15. if (s.contains("w")) {
    16. List.remove(s);
    17. }
    18. }
    19. System.out.println(List);
    20. }
    21. }

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

    原因

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

    解决方法

    1. package learn11;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. public class ListLearn {
    5. public static void main(String[] args) {
    6. List List = new ArrayList<>();
    7. List.add("learning");
    8. List.add("wyLearning");
    9. List.add("test");
    10. List.add("wy");
    11. List.add("wangying");
    12. List.add("wyy");
    13. for (int i = 0; i < List.size(); i++) {
    14. String s = List.get(i);
    15. if (s.contains("w")) {
    16. List.remove(s);
    17. i--;
    18. }
    19. }
    20. System.out.println(List);
    21. }
    22. }

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

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

    其他方法-迭代器遍历

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

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

    1. package learn11;
    2. import java.util.ArrayList;
    3. import java.util.Iterator;
    4. import java.util.List;
    5. public class ListLearn {
    6. public static void main(String[] args) {
    7. List List = new ArrayList<>();
    8. List.add("learning");
    9. List.add("wyLearning");
    10. List.add("test");
    11. List.add("wy");
    12. List.add("wangying");
    13. List.add("wyy");
    14. Iterator it = List.iterator();
    15. while (it.hasNext()) {
    16. String name = it.next();
    17. if(name.contains("w")) {
    18. List.remove(name);
    19. }
    20. }
    21. System.out.println(List);
    22. }
    23. }

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

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

    1. package learn11;
    2. import java.util.ArrayList;
    3. import java.util.Iterator;
    4. import java.util.List;
    5. public class ListLearn {
    6. public static void main(String[] args) {
    7. List List = new ArrayList<>();
    8. List.add("learning");
    9. List.add("wyLearning");
    10. List.add("test");
    11. List.add("wy");
    12. List.add("wangying");
    13. List.add("wyy");
    14. Iterator it = List.iterator();
    15. while (it.hasNext()) {
    16. String name = it.next();
    17. if(name.contains("w")) {
    18. it.remove();
    19. }
    20. }
    21. System.out.println(List);
    22. }
    23. }

    总结

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

  • 相关阅读:
    RabbitMQ之ttl(过期消息)解读
    统计十进制数对应二进制数中1的个数
    Spring Boot 优雅配置yml配置文件定义集合、数组和Map
    Dom Based XSS
    【java、微服务】MQ
    (免费领源码)java#Springboot#mysql装修选购网站99192-计算机毕业设计项目选题推荐
    httprunnet自动化测试实战
    YOLOPose实战:手把手实现单阶段的人体姿态估计+代码解读
    信息安全:网络安全漏洞防护技术原理与应用.
    【毕业设计】大数据分析的航空公司客户价值分析 - python
  • 原文地址:https://blog.csdn.net/MRJJ_9/article/details/133096533