Java错误笔记

1. ConcurrentModification Exception异常分析

调用list.remove()方法导致modCount和expectedModCount的值不一致。
注意,像使用for-each进行迭代实际上也会出现这种问题。
下面是分析的过程:

        Collection<String> songs = new ArrayList<>();
        songs.add("小苹果");
        songs.add("荷塘夜色");
        songs.add("黑色幽默");
        songs.add("发如雪");

        Iterator<String> it = songs.iterator();
        while(it.hasNext()){
            String name = it.next();
            System.out.println("元素为: " + name);
            if(name.equals("发如雪")){
                songs.remove(name);
            }
        }   

首先会调用it的hasNext方法来判断是否有下一个元素

        //当curor(指向的位置)和集合的长度不一致时,就表示还有元素
        public boolean hasNext() {
            return cursor != size;
        }

然后调用next方法取出该元素

        public E next() {
            //判断modCount 和 expectedModCount是否相等
            //如果不相等就抛出异常
            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)
                throw new ConcurrentModificationException();
        }

然后集合的元素是否等于”发如雪”,如果等于就删除它

        public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    //这里改变了modCount的值,并且size的大小也改变了
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

2.

你可能感兴趣的:(java)