【“调皮“的异常】——ConcurrentModificationException

1、概述

在写项目的时候,需要使用ForEach遍历将里面的数据根据操作实时更新,然后系统报了一个异常 ConcurrentModificationException ,就是这个"调皮"的异常,让我的数据实时更新不了了。

jdk文档的解释:当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。

通俗易懂地来说,就是使用 ForEach 遍历同时,进行删除,增加从而出现的异常。平常使用的ArrayList, HashMap都有可能抛出这种异常,粗心的话,很容易犯这种错误,导致线上事故!




2. 情景列举

ForEach 遍历就是 For(Object o : List) 这种遍历方式,众所周知,ForEach循环只是JAVA的一个语法糖,在字节码层面上,等同于迭代器循环遍历。在这种情形下,增加元素一定会抛出ConcurrentModificationException,

而删除元素在大多数情况下,会抛出ConcurrentModificationException(小知识,当且仅当删除小标为 size()-2,也就是倒数第二个元素的时候,不会抛出异常)。

这种情况下,会有异常抛出

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        for (Integer i : list) {
            if(i == 1){
                list.remove(i);
            }
        }




3. 如何避免该异常

(1) 通过集合的普通遍历方式(并非forEach方式,因为foreach本身也是一种迭代)

     for(i=0;i<size();i++)

(2)通过迭代器进行迭代删除:

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        Iterator<Integer> listIterator = list.iterator();

        while (listIterator.hasNext()){
            Integer next = listIterator.next();
            System.out.println(next);

            if (next==1) {
                listIterator.remove();
            }

        }

        System.out.println(list);
        //输出结果为:
                     1
                     2
                     3
                     [2, 3]



注意:修改操作也能这样进行修改,但是添加操作是不能从末尾开始添加的,只能从当前位置开始添加,并且要切换成列表迭代器,代码如下:

List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        ListIterator<Integer> listIterator = list.listIterator();
        while (listIterator.hasNext()){
            Integer next = listIterator.next();

            if (next==1) {
                listIterator.add(1111);
            }

        }

        System.out.println(list);
        //输出结果为: [1, 1111, 2, 3]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值