ConcurrentModificationException并发修改异常

ConcurrentModificationException并发修改异常

#ConcurrentModificationException

在学习List集合的时候,在遍历的时候修改元素,发现报了错误。

List<String> l=new ArrayList<String>();
        l.add("北京");
        l.add("南京");
        l.add("东京");

        Iterator<String> it=l.iterator();
        while(it.hasNext()){
            String ss=it.next();
            if(ss.equals("南京"))
            {
                l.add("上海");
            }
            System.out.println(ss);
        }

报错
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList I t r . c h e c k F o r C o m o d i f i c a t i o n ( A r r a y L i s t . j a v a : 909 ) a t j a v a . u t i l . A r r a y L i s t Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList Itr.checkForComodification(ArrayList.java:909)atjava.util.ArrayListItr.next(ArrayList.java:859)
at com.neu.test4.ListDemo.main(ListDemo.java:32)
原因就出在32行上的next方法出了问题,集合的迭代器是不允许在遍历的时候对集合集合进行操作的。
我们来看看API是怎么说的
在这里插入图片描述
看源码:因为我们的集合l是ArrayList的对象,且使用了里面的add()方法和Iterator方法。

public boolean add(E e) {
            modCount++;//5、而我们在操作时,实际修改次数会变化,但是预期修改次数不会变化。这就让我们在checkForComodification方法里比较两个值的时候不同,就会抛出并发修改异常。
            //而我们的modCount这个值来自于ArrayList,但是我们查看ArrayList却没有,那是因为ArrayList继承了AbstractList这个抽下类,而抽象类里面就有这个值。如下
            add(e, elementData, size);
            return true;
    }
protected transient int modCount = 0;//6、AbstractList里面的。一开始值为0,然后在调用next,会判断,可是我们在next方法里做了用了add方法,而add方法会修改modCount的值。造成异常。
public Iterator<E> iterator() {
        return new Itr();
    }

Iterator有返回了一个Itr对象。(在报错里面也可以看到)看next方法。

private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;//4、而在Itr类里面,已经将实际修改次数赋值给了期望修改次数。

        @SuppressWarnings("unchecked")
        public E next() {//1、在进入next方法时,会调用checkForComodification方法。如下
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
 final void checkForComodification() {
            if (modCount != expectedModCount)//2、而这个方法首先会比较两个值:modCount(实际修改集合的次数)和expectedModCount(预期修改集合的次数)。
                throw new ConcurrentModificationException();//3、判断,如果这两个值不相等,就会抛出我们所看到的ConcurrentModificationException异常。
        }

解决办法

可以用for循环遍历集合呀。哈哈哈哈,这样就不会报错了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值