ConcurrentModificationException并发修改异常

    科技2022-07-20  102

    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循环遍历集合呀。哈哈哈哈,这样就不会报错了。

    Processed: 0.011, SQL: 8