返回顶部
首页 > 资讯 > 后端开发 > JAVA >进阶JAVA篇- Collcetions 工具类与集合的并发修改异常问题
  • 876
分享到

进阶JAVA篇- Collcetions 工具类与集合的并发修改异常问题

javapythonwindows 2023-10-26 11:10:17 876人浏览 安东尼
摘要

目录         1.0 集合的并发修改问题                 1.1 如何解决集合的并发修改问题         2.0 Collcetions 工具类的说明         1.0 集合的并发修改问题        

目录

        1.0 集合的并发修改问题

                1.1 如何解决集合的并发修改问题

        2.0 Collcetions 工具类的说明


        1.0 集合并发修改问题

        我们可以简单的认为,就是使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。

代码如下:

import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class AbnORMal {    public static void main(String[] args) {        //创建对象,再添加数据        List list = new ArrayList<>();        list.add("张三");        list.add("陈七");        list.add("李麻子");        list.add("李四");        list.add("王五");        //利用迭代器进行遍历,先创建迭代器        Iterator iterator = list.iterator();        while (iterator.hasNext()){            String a = iterator.next();            if (a.contains("李")){                list.remove(a);            }        }        System.out.println(list);    }}

运行结果如下:

       

        像以上情况,一边遍历的时候去删除数据,直接会报错,原因是因为集合是一个可变的容器,每删一个数据,容器的大小都会改变,那么数据存放的位置也会相应的改变。迭代器遍历可能不好理解,我们就换成普通的 for 循环,但是两者的出现的 Bug 是一样的。

代码如下:

import java.util.ArrayList;import java.util.List;public class Text_For {    public static void main(String[] args) {        //创建对象,再添加数据        List list = new ArrayList<>();        list.add("张三");        list.add("陈七");        list.add("李麻子");        list.add("李四");        list.add("王五");        for (int i = 0; i < list.size(); i++) {            String a = list.get(i);            if (a.contains("李")){                list.remove(a);            }        }        System.out.println(list);    }}

运行结果如下:

        发现用 for 循环竟然不报错,原因可能是没有用迭代器遍历严谨吧,以上的两种代码的效果都是一样的,会出现 Bug ,就是本来要删除带 ”李“ 的名字,但是发现名字还有一个”李四“,没有被删除,那是什么原因呢?

        

        直接会把 ”李四“ 忽略掉,这就是这出现 Bug 的地方。

                1.1 如何解决集合的并发修改问题

        对于用普通的 for 循环来遍历的代码来说可以有两种方法;第一个方法就是每一次删除数据的时候,都要进行 i--; 第二方法就是从尾开始遍历。

代码如下:

第一种方法

import java.util.ArrayList;import java.util.List;public class Text_For {    public static void main(String[] args) {        //创建对象,再添加数据        List list = new ArrayList<>();        list.add("张三");        list.add("陈七");        list.add("李麻子");        list.add("李四");        list.add("王五");        for (int i = 0; i < list.size(); i++) {            String a = list.get(i);            if (a.contains("李")){                list.remove(a);                i--;            }        }        System.out.println(list);    }}

运行结果如下:

        成功把”李四“也删除掉了。

第二种方法

import java.util.ArrayList;import java.util.List;public class Text_For {    public static void main(String[] args) {        //创建对象,再添加数据        List list = new ArrayList<>();        list.add("张三");        list.add("陈七");        list.add("李麻子");        list.add("李四");        list.add("王五");        for (int i = list.size() - 1; i >= 0; i--) {            String a = list.get(i);            if (a.contains("李")){                list.remove(a);            }        }        System.out.println(list);    }}

运行结果如下:

        一样也可以把”李四“删除掉。

        对于用迭代器来遍历的代码来说,只能把集合对象.remove(String str) 换成迭代器对象.remove()

代码如下:

import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class Abnormal {    public static void main(String[] args) {        //创建对象,再添加数据        List list = new ArrayList<>();        list.add("张三");        list.add("陈七");        list.add("李麻子");        list.add("李四");        list.add("王五");        //利用迭代器进行遍历,先创建迭代器        Iterator iterator = list.iterator();        while (iterator.hasNext()){            String a = iterator.next();            if (a.contains("李")){                iterator.remove();            }        }        System.out.println(list);    }}

运行结果如下:

        也是可以的。

        对于增强 for 循环还有利用 Lambda 表达式的循环都不可以用来一边遍历集合,一边删除数据,无法解决集合的并发修改异常。

        2.0 Collcetions 工具类的说明

        是一个用来操作集合的工具类。

以代码为例来介绍具体的静态方法:

import java.util.ArrayList;import java.util.Collections;import java.util.List;public class Text_Collections {    public static void main(String[] args) {        String s1 = "李四";        String s2 = "张三";        String s3 = "王五";        String s4 = "张麻子";        List list = new ArrayList<>();        //1. addAll() 为集合批量添加数据        Collections.addAll(list,s1,s2,s3,s4);        System.out.println(list);        //输出结果为:[李四, 张三, 王五, 张麻子]        //2. shuffle() 打乱list集合中的元素顺序        Collections.shuffle(list);        System.out.println(list);        //输出结果为:[王五, 张麻子, 李四, 张三]        //3. sort() 对list集合的元素进行升序排序        Collections.sort(list);        System.out.println(list);        //输出结果为:[张三, 张麻子, 李四, 王五]    }}

运行结果如下:

         补充第三种方法,如果对自定的对象进行排序的话,默认的 sort 是会报错的,所以得自定义比较,创建一个比较器。

代码如下:

import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;public class Text_Collections {    public static void main(String[] args) {        Student s1 = new Student("张三",19);        Student s2 = new Student("李四",33);        Student s3 = new Student("王五",21);        List list = new ArrayList<>();        Collections.addAll(list,s1,s2,s3);        //自定义,根据年龄进行排序        Collections.sort(list, new Comparator() {            @Override            public int compare(Student o1, Student o2) {                return o1.getAge()- o2.getAge();            }        });        System.out.println(list);    }}

运行结果如下:

 



来源地址:https://blog.csdn.net/Tingfeng__/article/details/133965478

--结束END--

本文标题: 进阶JAVA篇- Collcetions 工具类与集合的并发修改异常问题

本文链接: https://lsjlt.com/news/458459.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作