java ArrayList中modCount的作用

Posted link

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java ArrayList中modCount的作用相关的知识,希望对你有一定的参考价值。

/**
     * The number of times this list has been <i>structurally modified</i>.
     * Structural modifications are those that change the size of the
     * list, or otherwise perturb it in such a fashion that iterations in
     * progress may yield incorrect results.
     *
     * <p>This field is used by the iterator and list iterator implementation
     * returned by the {@code iterator} and {@code listIterator} methods.
     * If the value of this field changes unexpectedly, the iterator (or list
     * iterator) will throw a {@code ConcurrentModificationException} in
     * response to the {@code next}, {@code remove}, {@code previous},
     * {@code set} or {@code add} operations.  This provides
     * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
     * the face of concurrent modification during iteration.
     *
     * <p><b>Use of this field by subclasses is optional.</b> If a subclass
     * wishes to provide fail-fast iterators (and list iterators), then it
     * merely has to increment this field in its {@code add(int, E)} and
     * {@code remove(int)} methods (and any other methods that it overrides
     * that result in structural modifications to the list).  A single call to
     * {@code add(int, E)} or {@code remove(int)} must add no more than
     * one to this field, or the iterators (and list iterators) will throw
     * bogus {@code ConcurrentModificationExceptions}.  If an implementation
     * does not wish to provide fail-fast iterators, this field may be
     * ignored.
     */
    protected transient int modCount = 0;
在注释里已经说明了The number of times this list has been structurally modified. 记录的是list被修改的次数;This field is used by the iterator and list iterator implementation 由迭代器实现使用。
在迭代时异常修改会抛异常ConcurrentModificationException 并发修改异常,说明在迭代时不能修改list
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String str = iterator.next();
            list.remove(str);
        }
    }
}

以上代码执行后抛异常

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    at java.util.ArrayList$Itr.next(ArrayList.java:859)
    at com.design.mode.Test2.main(Test2.java:15)

符合注释上的说明,既然说是由迭代器使用,那再看看迭代器代码(删除了不相干代码)

/**
     * 这里可以看出 迭代器是 ArrayList 的一个内部实现类 典型的迭代器模式
     */
    public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    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
         // 这里将 modCount 赋值给了 expectedModCount
        int expectedModCount = modCount;

        Itr() {}

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

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = 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 {
                this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            // 若修改后 modCount会变化 会与 expectedModCount 数值不相等
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

看源码可以得出获取迭代器时会将 expectedModCount 赋值为 modCount, 若在使用迭代器迭代期间修改列表则会导致两者不相等,调用next()时会进行checkForComodification检查抛异常。说明迭代时不可以进行修改操作。

modCount主要目的就是用来限制用户在迭代时修改列表,造成数据错乱

 

 

 

以上是关于java ArrayList中modCount的作用的主要内容,如果未能解决你的问题,请参考以下文章

Java 之 集合中的 modCount的作用

java modCount和fail-fast

集合类中modCount字段的作用

通过ArrayList对modCount的操作分析fail-fast 机制

modCount到底是干什么的呢

深入理解java集合框架之---------Arraylist集合 -----添加方法