zoukankan      html  css  js  c++  java
  • 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.
         * MARK:
         * 列表结构被修改的次数,在所有会修改列表的方法上都会 modCount++;
         * 在迭代器中控制并发
         */
        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主要目的就是用来限制用户在迭代时修改列表,造成数据错乱

     
  • 相关阅读:
    AFHTTPRequestOperationManager网络请求的时候添加一个菊花,requestmapping
    媒体层图形技术之Core Animation 学习笔记
    PHP自动判断字符集并转码
    用PHP实现游戏中的一些常见功能
    从几个简单的程序看PHP的垃圾回收机制
    递归遍历PHP多维数组
    CodeIgniter的缓存机制与使用方法
    PHP的内存泄露问题与垃圾回收
    记录一下PHP数组数据分页的方法
    PHP正则表达式移除超链接文本
  • 原文地址:https://www.cnblogs.com/zh-ch/p/12727250.html
Copyright © 2011-2022 走看看