遍历集合ConcurrentModificationException异常

本文详细解释了Java中遍历集合时可能出现的ConcurrentModificationException异常,包括异常产生的原因及解决办法,适用于单线程或多线程环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在遍历集合时,如果进行了增删操作,有时会抛出 java.util.ConcurrentModificationException异常。这类异常也被称为 fail-fast,它是Java集合的一种错误检测机制。

出现异常的原因:使用了iterator和foreach(底层也是使用了iterator的方式)进行遍历,并且遍历期间进行add或remove操作,那就有可能发生此异常。出现异常的关键就在于iterator的next()方法,下面是其源码

    public E next() {
        checkForComodification();
        try {
            E next = get(cursor);
            lastRet = cursor++;
            return next; 
        } catch (IndexOutOfBoundsException e) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }
其中的checkForComodification()方法会检查集合的大小,如何跟预期的,也就是与list.iterator()调用时的集合大小不一致,就是抛异常。

单线程下的解决方法

        // 使用最原始的下标遍历方式
        for ( int i = 0; i < myList.size(); i++) {
            String value = myList.get(i);
            if (value.equals( "3")) {
                myList.remove(value); // ok
                i--; // 因为位置发生改变,所以必须修改i的位置
            }
        }
        // 使用iterator的remove方法,而不使用集合本身的remove方法
        for (Iterator<string> it = myList.iterator(); it.hasNext();) {
            String value = it.next();
            if (value.equals( "3")) {
                it.remove(); // ok
            }
        }
        // 把需要删除的元素添加到临时集合中,遍历结束后使用removeAll方法删除
        List<string> templist = new ArrayList<string>();
        for (String value : myList) {
            if (value.equals( "3")) {
                templist.remove(value); }
            }
        }
        myList.removeAll(templist);
多线程下的解决方法
尽量使用java.util.concurrent包下的集合,不推荐使用synchronizer来加锁或者使用Collections.synchronizedList,效率比较慢,会导致多个线程遍历时阻塞。推荐使用CopyOnWriteArrayList,对于map,在多线程情况下,也推荐使用ConcurrentHashMap。

    List<string> myList = new CopyOnWriteArrayList<string>();
    myList.add("a");
    myList.add("b");
    myList.add("c");
    for (int i = 0; i < myList.size(); i++) {
        String value = myList.get(i);
        if (value.equals( "3")) {
            myList.remove(value);
            i--; // 记得下标减1,使得下次遍历能遍历到删除元素的下个元素,否则会跳过该元素
        } 
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值