java.util.ConcurrentModificationException异常详解

今天学习java集合的时候遇到了以下问题,下面是出现异常的代码
public class CollectionMapDemo {
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        Iterator it = collection.iterator();
        collection.add("a");
        collection.add("b");
        while (it.hasNext()) {
            // Object o = it.next();
            String s = it.next().toString();
            System.out.println(s);
        }
    }
}
运行结果是:
异常原因:在实现iterator之后对集合元素进行操作导致迭代器的modCount和expectedModCount的值不一致

让我们来看一下ArrayList实现iterator的源码
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;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        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];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }
    final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
}

从以上代码可以看出开始时,expectedModCount(期望修改次数) 和 modCount(实际修改次数)是相同的,但是经过 collection.add("a"); collection.add("b");修改之后modCount(实际修改次数)已经变化,导致在最后执行checkForComodification方法时,出现ConcurrentModificationException异常,解决方法就是在实现iterator接口之前,完成对结合的操作

同理以下代码也会出错
public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(2);
    Iterator<Integer> iterator = list.iterator();
    while(iterator.hasNext()){
        Integer integer = iterator.next();
        if(integer==2)
            list.remove(integer);
    }
}
当调用了list.remove方法之后,modCount(实际修改次数)已经变化,同样也会出现ConcurrentModificationException异常。这里就可以调用实现了iterator自身的remove,在代码中就不会出错了。解决办法是list.remove()改为iterator.remove()


猜你喜欢

转载自blog.csdn.net/sinat_29774479/article/details/79871396
今日推荐