Java ConcurrentModificationException报错处理

 如果在遍历集合过程中删除某个元素,并且继续遍历则会引发ConcurrentModificationException

/**
 * ConcurrentModificationException
 */
public class Demo{
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Iterator<Integer> it = list.iterator();
        while (it.hasNext()){
            Integer value = it.next();
            //删除集合中值为3的元素
            if(value.equals(3)){
                list.remove(value);
            }
        }
        //查看集合中剩余元素
        for (Integer value : list) {
            System.out.println(value);
        }
    }
}

结果如下:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)

提供一个解决方案,删除元素后停止遍历,即遍历一次删除一个。

修改代码后

/**
 * 处理ConcurrentModificationException
 */
public class Demo{
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Iterator<Integer> it = list.iterator();
        while (it.hasNext()){
            Integer value = it.next();
            //删除集合中值为3的元素
            if(value.equals(3)){
                list.remove(value);
                break;//新增加的代码块
            }
        }
        //查看集合中剩余元素
        for (Integer value : list) {
            System.out.println(value);
        }
    }
}

结果如下:

1
2
4
5

若要删除多个相同元素,多次遍历、每次遍历删除一个即可

修改代码后

public class ConcurrentModificationException {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(3);
        list.add(4);
        list.add(5);

        delEle(list,3);
        
        //查看集合内剩余元素
        for (Integer ele : list) {
            System.out.println(ele);
        }
    }

    //批量删除元素
    public static <T> void delEle(ArrayList<T> list,T t) {
        boolean isDel=false;//检测集合是否还存在要删除的元素
        do {
            Iterator<T> it = list.iterator();
            isDel=false;//每次循环删除成功后重置
            //删除单个元素
            while (it.hasNext()) {
                T ele = it.next();
                if (ele.equals(t)) {
                    list.remove(ele);
                    isDel=true;
                    break;//删除成功后开始下一轮循环,继续寻找要删除的元素
                }
            }
        } while (isDel);
    }
}

 结果如下:

1

2

4

5

其他的解决方案

原文链接:https://blog.csdn.net/androiddevelop/article/details/21509345


            // 1 使用Iterator提供的remove方法,用于删除当前元素
            for (Iterator<String> it = myList.iterator(); it.hasNext();) {
                String value = it.next();
                 if (value.equals( "3")) {
                     it.remove();  // ok
                }
           }
           System. out.println( "List Value:" + myList.toString());
      
            // 2 建一个集合,记录需要删除的元素,之后统一删除             
           List<String> templist = new ArrayList<String>();
            for (String value : myList) {
                 if (value.equals( "3")) {
                     templist.remove(value);
                }
           }
            // 可以查看removeAll源码,其中使用Iterator进行遍历
           myList.removeAll(templist);
           System. out.println( "List Value:" + myList.toString());        
        
             // 3. 使用线程安全CopyOnWriteArrayList进行删除操作
           List<String> myList = new CopyOnWriteArrayList<String>();
           myList.add( "1");
           myList.add( "2");
           myList.add( "3");
           myList.add( "4");
           myList.add( "5");
 
           Iterator<String> it = myList.iterator();
 
            while (it.hasNext()) {
                String value = it.next();
                 if (value.equals( "3")) {
                     myList.remove( "4");
                     myList.add( "6");
                     myList.add( "7");
                }
           }
           System. out.println( "List Value:" + myList.toString());
          
            // 4. 不使用Iterator进行遍历,需要注意的是自己保证索引正常
            for ( int i = 0; i < myList.size(); i++) {
                String value = myList.get(i);
                System. out.println( "List Value:" + value);
                 if (value.equals( "3")) {
                     myList.remove(value);  // ok
                     i--; // 因为位置发生改变,所以必须修改i的位置
                }
           }
           System. out.println( "List Value:" + myList.toString());
————————————————
版权声明:本文为CSDN博主「love_world_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/androiddevelop/article/details/21509345

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值