• Vector源码详解(基于jdk1.8.0_231)


    1. Vector简介

    • Vector继承AbstractList实现了List, RandomAccess, Cloneable, java.io.Serializable接口;
    • Vector本质上是线程安全的动态可扩容的数组,区别于ArrayList是非线程安全的动态可扩容的数组,两者的API基本相同;
    • Vector扩容可以自定义或默认每次扩容后新容量=2*老容量;
    • Vector即使是线程安全的,由于迭代器的特性,Vector中fail-fast机制仍然是不可缺少的;
    • Vector提高了可以直接得到列表当前容量的API capacity()函数,而ArrayList不可;

    2. Vector UML简图

    API 概述

    Vector类中定义的字段

    protected Object[]  elementData; //存储元素的数组
    protected int       elementCount;//记录动态数组的size,实际含的元素个数
    protected int       capacityIncrement; //自定义的每次扩容大小,在初始化时设定
    private static final long serialVersionUID = -2767605614048989439L;
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    • Vector类中引入了capacityIncrement字段,可以有用户定义每次扩容的大小,确定就是一次指定,以后扩容都扩大一样的大小,即为capacityInCrement.
      使用public Vector(int initialCapacity, int capacityIncrement)类型的构造函数即可指定.
      *MAX_ARRAY_SIZE 是由于某些虚拟机将header words也保存在数据中,为了这类虚拟机,故数据扩容的最大容量为MAX_ARRAY_SIZE.当然,对于没有将header words 保存在数据中的虚拟机,扩容机制可能仍会扩成Integer.MAX_VALUE.
      具体的细节见源码hugeCapactiy函数。

    直接继承超类的字段

    protected transient int modCount = 0; //继承自AbstractList超类
    

    构造函数

    public       Vector(int initialCapacity, int capacityIncrement) //每次扩容都按照指定的大小
    public       Vector(int initialCapacity) //初始化容量大小,扩容机制采用2倍扩容
    public       Vector()  //默认容量为10,扩容机制采用2倍扩容
    public       Vector(Collection<? extends E> c) //一次性加入一个集合,容量指定为加入的元素的个数
    

    Override或新增的public protected方法

    -------------将列表转成数组的方法------------------
    synchronized void             copyInto(Object[] anArray)
    synchronized Object[]         toArray() 
    synchronized <T> T[]          toArray(T[] a)
    --------------修改列表容量的方法-------------------
    synchronized void             trimToSize()
    synchronized void             ensureCapacity(int minCapacity) //方法内调用ensureCapacityHelper->grow扩容
    --------------得到capacity size 判空的方法----------
    synchronized                  int capacity()
    synchronized                  int size()
    synchronized boolean          isEmpty()
    --------------得到迭代器的方法-----------------------
    Enumeration<E>                 elements() 
    synchronized ListIterator<E>   listIterator(int index) 
    synchronized ListIterator<E>   listIterator()
    synchronized Iterator<E>       iterator()
    --------------查询元素位置和是否存在的方法------------
    boolean                        contains(Object o)
    synchronized boolean           containsAll(Collection<?> c)
    int                            indexOf(Object o)
    synchronized int               indexOf(Object o, int index)
    synchronized int               lastIndexOf(Object o)
    synchronized int               lastIndexOf(Object o, int index)
    
    ------------返回元素的方法---------------------------
    synchronized E                 elementAt(int index)
    synchronized E                 firstElement()
    synchronized E                 lastElement() 
    E                              elementData(int index)
    synchronized E                 get(int index)
    ------------修改元素的方法----------------------------
    synchronized void              setElementAt(E obj, int index) 
    synchronized E                 set(int index, E element)
    ------------删除元素的方法----------------------------
    synchronized void               removeElementAt(int index)
    synchronized boolean            removeElement(Object obj) 
    synchronized void               removeAllElements()
    void                            clear()  //等价于removeAllElements()
    boolean                         remove(Object o) 
    synchronized E                  remove(int index)
    synchronized boolean            removeAll(Collection<?> c)
    synchronized boolean            retainAll(Collection<?> c)
    -------------增加元素的方法-----------------------------
    synchronized void               insertElementAt(E obj, int index) 
    synchronized void               addElement(E obj)
    void                            add(int index, E element)
    synchronized boolean            add(E e) 
    synchronized boolean            addAll(Collection<? extends E> c) 
    synchronized boolean            addAll(int index, Collection<? extends E> c)
    -----------------克隆列表的方法-------------------------
    synchronized Object             clone() 
    -----------返回子列表的方法-----------------------------
    synchronized List<E>            subList(int fromIndex, int toIndex)
    
    ----------Override超类的方法,非同步方法变同步------------
    synchronized boolean            equals(Object o) //继承自AbstractList
    synchronized int                hashCode() //继承自AbstractList
    synchronized String             toString() //继承自AbstractColletion
    -----------protected方法--------------------------------
    synchronized void removeRange(int fromIndex, int toIndex)
    ------------java8函数新加的方法--------------------------
    synchronized void forEach(Consumer<? super E> action) 
    synchronized boolean removeIf(Predicate<? super E> filter)
    synchronized void replaceAll(UnaryOperator<E> operator)
    synchronized void sort(Comparator<? super E> c)
    Spliterator<E> spliterator()
    ----------奇葩的一个方法---------------------------------
    synchronized                  void setSize(int newSize)
    

    来自接口的default方法或直接继承超类的方法

    default Stream<E> stream()
    default Stream<E> parallelStream() 
    
    

    private方法

    ----------扩容的方法-----------
    void             ensureCapacityHelper(int minCapacity) 
    void             grow(int minCapacity)
    static int       hugeCapacity(int minCapacity)
    void readObject(ObjectInputStream in)
    void writeObject(java.io.ObjectOutputStream s)
    

    3. Vector 源码介绍(基于jdk1.8.0_231)

    package java.util;
    
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.StreamCorruptedException;
    import java.util.function.Consumer;
    import java.util.function.Predicate;
    import java.util.function.UnaryOperator;
    
    public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        /**
         * The array buffer into which the components of the vector are
         * stored. The capacity of the vector is the length of this array buffer,
         * and is at least large enough to contain all the vector's elements.
         *
         * <p>Any array elements following the last element in the Vector are null.
         *
         * @serial
         */
        //存放数据的地方
        protected Object[] elementData;
    
        /**
         * The number of valid components in this {@code Vector} object.
         * Components {@code elementData[0]} through
         * {@code elementData[elementCount-1]} are the actual items.
         *
         * @serial
         */
        //记录存放Vector中实际含有的元素个数,
        protected int elementCount;
    
        /**
         * The amount by which the capacity of the vector is automatically
         * incremented when its size becomes greater than its capacity.  If
         * the capacity increment is less than or equal to zero, the capacity
         * of the vector is doubled each time it needs to grow.
         *
         * @serial
         */
        //
        protected int capacityIncrement;
    
        /** use serialVersionUID from JDK 1.0.2 for interoperability */
        private static final long serialVersionUID = -2767605614048989439L;
    
        /**
         * Constructs an empty vector with the specified initial capacity and
         * capacity increment.
         *
         * @param   initialCapacity     the initial capacity of the vector
         * @param   capacityIncrement   the amount by which the capacity is
         *                              increased when the vector overflows
         * @throws IllegalArgumentException if the specified initial capacity
         *         is negative
         */
        public Vector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            this.elementData = new Object[initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }
    
        /**
         * Constructs an empty vector with the specified initial capacity and
         * with its capacity increment equal to zero.
         *
         * @param   initialCapacity   the initial capacity of the vector
         * @throws IllegalArgumentException if the specified initial capacity
         *         is negative
         */
        public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }
    
        /**
         * Constructs an empty vector so that its internal data array
         * has size {@code 10} and its standard capacity increment is
         * zero.
         */
        //无参构造函数,容量初始化为10
        public Vector() {
            this(10);
        }
    
        /**
         * Constructs a vector containing the elements of the specified
         * collection, in the order they are returned by the collection's
         * iterator.
         *
         * @param c the collection whose elements are to be placed into this
         *       vector
         * @throws NullPointerException if the specified collection is null
         * @since   1.2
         */
        //直接将一个集合加入Vector中,容量即为集合的长度
        public Vector(Collection<? extends E> c) {
            elementData = c.toArray();
            elementCount = elementData.length;
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
        }
    
        /**
         * Copies the components of this vector into the specified array.
         * The item at index {@code k} in this vector is copied into
         * component {@code k} of {@code anArray}.
         *
         * @param  anArray the array into which the components get copied
         * @throws NullPointerException if the given array is null
         * @throws IndexOutOfBoundsException if the specified array is not
         *         large enough to hold all the components of this vector
         * @throws ArrayStoreException if a component of this vector is not of
         *         a runtime type that can be stored in the specified array
         * @see #toArray(Object[])
         */
        //将vector列表拷贝给另一个列表
        public synchronized void copyInto(Object[] anArray) {
            System.arraycopy(elementData, 0, anArray, 0, elementCount); 
        }
    
        /**
         * Trims the capacity of this vector to be the vector's current
         * size. If the capacity of this vector is larger than its current
         * size, then the capacity is changed to equal the size by replacing
         * its internal data array, kept in the field {@code elementData},
         * with a smaller one. An application can use this operation to
         * minimize the storage of a vector.
         */
        //将vector容量收缩实际含的元素个数 
        public synchronized void trimToSize() {
            modCount++;
            int oldCapacity = elementData.length;
            if (elementCount < oldCapacity) {
                elementData = Arrays.copyOf(elementData, elementCount);
            }
        }
    
        /**
         * Increases the capacity of this vector, if necessary, to ensure
         * that it can hold at least the number of components specified by
         * the minimum capacity argument.
         *
         * <p>If the current capacity of this vector is less than
         * {@code minCapacity}, then its capacity is increased by replacing its
         * internal data array, kept in the field {@code elementData}, with a
         * larger one.  The size of the new data array will be the old size plus
         * {@code capacityIncrement}, unless the value of
         * {@code capacityIncrement} is less than or equal to zero, in which case
         * the new capacity will be twice the old capacity; but if this new size
         * is still smaller than {@code minCapacity}, then the new capacity will
         * be {@code minCapacity}.
         *
         * @param minCapacity the desired minimum capacity
         */
        //检查当前容量是否满足存储元素的最小需要,不够就需要扩容了
        public synchronized void ensureCapacity(int minCapacity) {
            if (minCapacity > 0) {
                modCount++;
                ensureCapacityHelper(minCapacity);
            }
        }
    
        /**
         * This implements the unsynchronized semantics of ensureCapacity.
         * Synchronized methods in this class can internally call this
         * method for ensuring capacity without incurring the cost of an
         * extra synchronization.
         *
         * @see #ensureCapacity(int)
         */
        //容量助手,容量不满足最小容量需求,就利用grow函数扩容
        private void ensureCapacityHelper(int minCapacity) {
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        /**
         * The maximum size of array to allocate.
         * Some VMs reserve some header words in an array.
         * Attempts to allocate larger arrays may result in
         * OutOfMemoryError: Requested array size exceeds VM limit
         */
        //针对某些虚拟机,Vector容量的最大值,为Integer.MAX_VALUE-8,某些可扩容成Interger.MAX_VALUE
        //所以对于上述情况,类库涉及采用了一种安全策略,如果没扩容前已经大于Integer.MAX_VALUE-8,那直接扩充为Interger.MAX_VALUE
        //如果没扩容前小于Integer.MAX_VALUE-8,扩容后超过Integer.MAX_VALUE-8,为了安全起见,最大就扩充成Integer.MAX_VALUE-8
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        
        //扩容机制:如果Vector示例初始化时,设置好了每次扩容的大小是时,每次扩容都是 新容量 = 原容量 + 设置好的扩容大小,
        //如果没有设置好扩容大小,新容量 = 2 * 原容量;
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);
            //下面的一些处理tricks和ArrayList的grow函数一样
            if (newCapacity - minCapacity < 0)   
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        //这个hugeCapacity在字段Integer.MAX_VALUE处以说明,是为了自适应虚拟机
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    
        /**
         * Sets the size of this vector. If the new size is greater than the
         * current size, new {@code null} items are added to the end of
         * the vector. If the new size is less than the current size, all
         * components at index {@code newSize} and greater are discarded.
         *
         * @param  newSize   the new size of this vector
         * @throws ArrayIndexOutOfBoundsException if the new size is negative
         */
        //这个方法很鸡肋,设置Vector的size(即手动设置elementCount,不是容量哦)
        //很傻逼的方法,newSize设置比elementCount大,但实际元素那么多,大概率会重新修改原容量大小,
        //如果newSize <= elementCount,会把索引newSize到elementCount之间的元素置为null,抹掉了原元素
        //背离了Vector动态扩容的初衷了。乱设计API,ArrayList就不会出现这反原则的傻逼方法
        public synchronized void setSize(int newSize) {
            modCount++;
            if (newSize > elementCount) {
                ensureCapacityHelper(newSize);
            } else {
                for (int i = newSize ; i < elementCount ; i++) {
                    elementData[i] = null;
                }
            }
            elementCount = newSize;
        }
    
        /**
         * Returns the current capacity of this vector.
         *
         * @return  the current capacity (the length of its internal
         *          data array, kept in the field {@code elementData}
         *          of this vector)
         */
        //得到Vector的容量,请区分容量和数组长度和size elementCount四个概念
        //容量capacity= elementData.length; size = elementCount =实际存放元素的个数
        public synchronized int capacity() {
            return elementData.length;
        }
    
        /**
         * Returns the number of components in this vector.
         *
         * @return  the number of components in this vector
         */
        //返回Vector的size(即elementCount 实际存放元素的个数)
        public synchronized int size() {
            return elementCount;
        }
    
        /**
         * Tests if this vector has no components.
         *
         * @return  {@code true} if and only if this vector has
         *          no components, that is, its size is zero;
         *          {@code false} otherwise.
         */
       //检查Vector是否为空,为空,返回true
        public synchronized boolean isEmpty() {
            return elementCount == 0;
        }
    
        /**
         * Returns an enumeration of the components of this vector. The
         * returned {@code Enumeration} object will generate all items in
         * this vector. The first item generated is the item at index {@code 0},
         * then the item at index {@code 1}, and so on.
         *
         * @return  an enumeration of the components of this vector
         * @see     Iterator
         */
        //相当于Iterator迭代器,由于历史原因,这里称为枚举器,不过只有拿到对象锁时候,才会迭代
        public Enumeration<E> elements() {
            return new Enumeration<E>() {
                int count = 0;
    
                public boolean hasMoreElements() { //相当于hasNext()
                    return count < elementCount;
                }
    
                public E nextElement() {  //相当于next()
                    synchronized (Vector.this) {
                        if (count < elementCount) {
                            return elementData(count++);
                        }
                    }
                    throw new NoSuchElementException("Vector Enumeration");
                }
            };
        }
    
        /**
         * Returns {@code true} if this vector contains the specified element.
         * More formally, returns {@code true} if and only if this vector
         * contains at least one element {@code e} such that
         * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
         *
         * @param o element whose presence in this vector is to be tested
         * @return {@code true} if this vector contains the specified element
         */
        //检查是否包含对象o
        public boolean contains(Object o) {
            return indexOf(o, 0) >= 0;
        }
    
        /**
         * Returns the index of the first occurrence of the specified element
         * in this vector, or -1 if this vector does not contain the element.
         * More formally, returns the lowest index {@code i} such that
         * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
         * or -1 if there is no such index.
         *
         * @param o element to search for
         * @return the index of the first occurrence of the specified element in
         *         this vector, or -1 if this vector does not contain the element
         */
        //得到对象o的索引
        public int indexOf(Object o) {
            return indexOf(o, 0);
        }
    
        /**
         * Returns the index of the first occurrence of the specified element in
         * this vector, searching forwards from {@code index}, or returns -1 if
         * the element is not found.
         * More formally, returns the lowest index {@code i} such that
         * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
         * or -1 if there is no such index.
         *
         * @param o element to search for
         * @param index index to start searching from
         * @return the index of the first occurrence of the element in
         *         this vector at position {@code index} or later in the vector;
         *         {@code -1} if the element is not found.
         * @throws IndexOutOfBoundsException if the specified index is negative
         * @see     Object#equals(Object)
         */
        //从index位置开始遍历,得到对象o的位置,没有返回-1
        public synchronized int indexOf(Object o, int index) {
            if (o == null) {
                for (int i = index ; i < elementCount ; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = index ; i < elementCount ; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }
    
        /**
         * Returns the index of the last occurrence of the specified element
         * in this vector, or -1 if this vector does not contain the element.
         * More formally, returns the highest index {@code i} such that
         * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
         * or -1 if there is no such index.
         *
         * @param o element to search for
         * @return the index of the last occurrence of the specified element in
         *         this vector, or -1 if this vector does not contain the element
         */
        //indexOf都是以index位置开始从前往后找,lastIndexOf都是以index位置开始从后往前找
        public synchronized int lastIndexOf(Object o) {
            return lastIndexOf(o, elementCount-1);
        }
    
        /**
         * Returns the index of the last occurrence of the specified element in
         * this vector, searching backwards from {@code index}, or returns -1 if
         * the element is not found.
         * More formally, returns the highest index {@code i} such that
         * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
         * or -1 if there is no such index.
         *
         * @param o element to search for
         * @param index index to start searching backwards from
         * @return the index of the last occurrence of the element at position
         *         less than or equal to {@code index} in this vector;
         *         -1 if the element is not found.
         * @throws IndexOutOfBoundsException if the specified index is greater
         *         than or equal to the current size of this vector
         */
        public synchronized int lastIndexOf(Object o, int index) {
            if (index >= elementCount)
                throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
    
            if (o == null) {
                for (int i = index; i >= 0; i--)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = index; i >= 0; i--)   //傻逼设计,不如从size找到index好,ArrayList已修正
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }
    
        /**
         * Returns the component at the specified index.
         *
         * <p>This method is identical in functionality to the {@link #get(int)}
         * method (which is part of the {@link List} interface).
         *
         * @param      index   an index into this vector
         * @return     the component at the specified index
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         */
        //返回index位置的元素
        public synchronized E elementAt(int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
    
            return elementData(index);
        }
    
        /**
         * Returns the first component (the item at index {@code 0}) of
         * this vector.
         *
         * @return     the first component of this vector
         * @throws NoSuchElementException if this vector has no components
         */
        //返回第一个元素
        public synchronized E firstElement() {
            if (elementCount == 0) {
                throw new NoSuchElementException();
            }
            return elementData(0);
        }
    
        /**
         * Returns the last component of the vector.
         *
         * @return  the last component of the vector, i.e., the component at index
         *          <code>size()&nbsp;-&nbsp;1</code>.
         * @throws NoSuchElementException if this vector is empty
         */
        //返回最后一个元素
        public synchronized E lastElement() {
            if (elementCount == 0) {
                throw new NoSuchElementException();
            }
            return elementData(elementCount - 1);
        }
    
        /**
         * Sets the component at the specified {@code index} of this
         * vector to be the specified object. The previous component at that
         * position is discarded.
         *
         * <p>The index must be a value greater than or equal to {@code 0}
         * and less than the current size of the vector.
         *
         * <p>This method is identical in functionality to the
         * {@link #set(int, Object) set(int, E)}
         * method (which is part of the {@link List} interface). Note that the
         * {@code set} method reverses the order of the parameters, to more closely
         * match array usage.  Note also that the {@code set} method returns the
         * old value that was stored at the specified position.
         *
         * @param      obj     what the component is to be set to
         * @param      index   the specified index
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         */
        //更新index位置的元素为obj
        public synchronized void setElementAt(E obj, int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                         elementCount);
            }
            elementData[index] = obj;
        }
    
        /**
         * Deletes the component at the specified index. Each component in
         * this vector with an index greater or equal to the specified
         * {@code index} is shifted downward to have an index one
         * smaller than the value it had previously. The size of this vector
         * is decreased by {@code 1}.
         *
         * <p>The index must be a value greater than or equal to {@code 0}
         * and less than the current size of the vector.
         *
         * <p>This method is identical in functionality to the {@link #remove(int)}
         * method (which is part of the {@link List} interface).  Note that the
         * {@code remove} method returns the old value that was stored at the
         * specified position.
         *
         * @param      index   the index of the object to remove
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         */
        //删除index位置的元素
        public synchronized void removeElementAt(int index) {
            modCount++;
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                         elementCount);
            }
            else if (index < 0) {
                throw new ArrayIndexOutOfBoundsException(index);
            }
            int j = elementCount - index - 1;
            if (j > 0) {
                System.arraycopy(elementData, index + 1, elementData, index, j); //把index后的元素一次往前移动1位
            }
            elementCount--;
            elementData[elementCount] = null; /* to let gc do its work */ 
        }
    
        /**
         * Inserts the specified object as a component in this vector at the
         * specified {@code index}. Each component in this vector with
         * an index greater or equal to the specified {@code index} is
         * shifted upward to have an index one greater than the value it had
         * previously.
         *
         * <p>The index must be a value greater than or equal to {@code 0}
         * and less than or equal to the current size of the vector. (If the
         * index is equal to the current size of the vector, the new element
         * is appended to the Vector.)
         *
         * <p>This method is identical in functionality to the
         * {@link #add(int, Object) add(int, E)}
         * method (which is part of the {@link List} interface).  Note that the
         * {@code add} method reverses the order of the parameters, to more closely
         * match array usage.
         *
         * @param      obj     the component to insert
         * @param      index   where to insert the new component
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index > size()})
         */
        // 在index位置插入obj
        //Vecttor从index位置开始一次后移1位(逻辑上应该是elementCount先往后移动1位,接着之前元素依次往后覆盖)
        public synchronized void insertElementAt(E obj, int index) {
            modCount++;
            if (index > elementCount) {
                throw new ArrayIndexOutOfBoundsException(index
                                                         + " > " + elementCount);
            }
            ensureCapacityHelper(elementCount + 1);
            System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
            elementData[index] = obj;
            elementCount++;
        }
    
        /**
         * Adds the specified component to the end of this vector,
         * increasing its size by one. The capacity of this vector is
         * increased if its size becomes greater than its capacity.
         *
         * <p>This method is identical in functionality to the
         * {@link #add(Object) add(E)}
         * method (which is part of the {@link List} interface).
         *
         * @param   obj   the component to be added
         */
        //在尾部添加一个新元素obj
        public synchronized void addElement(E obj) {
            modCount++;
            ensureCapacityHelper(elementCount + 1); //先检查是否需要扩容
            elementData[elementCount++] = obj;
        }
    
        /**
         * Removes the first (lowest-indexed) occurrence of the argument
         * from this vector. If the object is found in this vector, each
         * component in the vector with an index greater or equal to the
         * object's index is shifted downward to have an index one smaller
         * than the value it had previously.
         *
         * <p>This method is identical in functionality to the
         * {@link #remove(Object)} method (which is part of the
         * {@link List} interface).
         *
         * @param   obj   the component to be removed
         * @return  {@code true} if the argument was a component of this
         *          vector; {@code false} otherwise.
         */
        //按位置移除obj 
        public synchronized boolean removeElement(Object obj) {
            modCount++;
            int i = indexOf(obj); //先顺序得到obj的索引
            if (i >= 0) {
                removeElementAt(i); //在按索引移除
                return true;
            }
            return false; //没有obj
        }
    
        /**
         * Removes all components from this vector and sets its size to zero.
         *
         * <p>This method is identical in functionality to the {@link #clear}
         * method (which is part of the {@link List} interface).
         */
        //清空Vector实例,相当于ArrayList的clear()
        public synchronized void removeAllElements() {
            modCount++;
            // Let gc do its work
            for (int i = 0; i < elementCount; i++)
                elementData[i] = null;
    
            elementCount = 0;
        }
    
        /**
         * Returns a clone of this vector. The copy will contain a
         * reference to a clone of the internal data array, not a reference
         * to the original internal data array of this {@code Vector} object.
         *
         * @return  a clone of this vector
         */
        //浅拷贝,如果元素都是基本类型就是深拷贝
        public synchronized Object clone() {
            try {
                @SuppressWarnings("unchecked")
                    Vector<E> v = (Vector<E>) super.clone(); //Object的clone()
                v.elementData = Arrays.copyOf(elementData, elementCount);
                v.modCount = 0;
                return v;
            } catch (CloneNotSupportedException e) {
                // this shouldn't happen, since we are Cloneable
                throw new InternalError(e);
            }
        }
    
        /**
         * Returns an array containing all of the elements in this Vector
         * in the correct order.
         *
         * @since 1.2
         */
        //Vector列表转数组
        public synchronized Object[] toArray() {
            return Arrays.copyOf(elementData, elementCount);
        }
    
        /**
         * Returns an array containing all of the elements in this Vector in the
         * correct order; the runtime type of the returned array is that of the
         * specified array.  If the Vector fits in the specified array, it is
         * returned therein.  Otherwise, a new array is allocated with the runtime
         * type of the specified array and the size of this Vector.
         *
         * <p>If the Vector fits in the specified array with room to spare
         * (i.e., the array has more elements than the Vector),
         * the element in the array immediately following the end of the
         * Vector is set to null.  (This is useful in determining the length
         * of the Vector <em>only</em> if the caller knows that the Vector
         * does not contain any null elements.)
         *
         * @param a the array into which the elements of the Vector are to
         *          be stored, if it is big enough; otherwise, a new array of the
         *          same runtime type is allocated for this purpose.
         * @return an array containing the elements of the Vector
         * @throws ArrayStoreException if the runtime type of a is not a supertype
         * of the runtime type of every element in this Vector
         * @throws NullPointerException if the given array is null
         * @since 1.2
         */
        @SuppressWarnings("unchecked")
        public synchronized <T> T[] toArray(T[] a) {
            if (a.length < elementCount)
                return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
    
            System.arraycopy(elementData, 0, a, 0, elementCount);
    
            if (a.length > elementCount)
                a[elementCount] = null;
    
            return a;
        }
    
        // Positional Access Operations
        //返回index位置的元素
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        /**
         * Returns the element at the specified position in this Vector.
         *
         * @param index index of the element to return
         * @return object at the specified index
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *            ({@code index < 0 || index >= size()})
         * @since 1.2
         */
       //get区别于elementData唯一之处就是上界检查
        public synchronized E get(int index) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            return elementData(index);
        }
    
        /**
         * Replaces the element at the specified position in this Vector with the
         * specified element.
         *
         * @param index index of the element to replace
         * @param element element to be stored at the specified position
         * @return the element previously at the specified position
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         * @since 1.2
         */
        //更新index位置的元素为element,返回老元素,区别于setElementAt的是set有返回老元素,而前者没有返回值
        public synchronized E set(int index, E element) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
    
        /**
         * Appends the specified element to the end of this Vector.
         *
         * @param e element to be appended to this Vector
         * @return {@code true} (as specified by {@link Collection#add})
         * @since 1.2
         */
        //在尾部添加一个新元素
        public synchronized boolean add(E e) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }
    
        /**
         * Removes the first occurrence of the specified element in this Vector
         * If the Vector does not contain the element, it is unchanged.  More
         * formally, removes the element with the lowest index i such that
         * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
         * an element exists).
         *
         * @param o element to be removed from this Vector, if present
         * @return true if the Vector contained the specified element
         * @since 1.2
         */
        //删除一个对象o,等价于removeElemet(E obj)
        public boolean remove(Object o) {
            return removeElement(o);
        }
    
        /**
         * Inserts the specified element at the specified position in this Vector.
         * Shifts the element currently at that position (if any) and any
         * subsequent elements to the right (adds one to their indices).
         *
         * @param index index at which the specified element is to be inserted
         * @param element element to be inserted
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index > size()})
         * @since 1.2
         */
        
        public void add(int index, E element) {
            insertElementAt(element, index);
        }
    
        /**
         * Removes the element at the specified position in this Vector.
         * Shifts any subsequent elements to the left (subtracts one from their
         * indices).  Returns the element that was removed from the Vector.
         *
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         * @param index the index of the element to be removed
         * @return element that was removed
         * @since 1.2
         */
        public synchronized E remove(int index) {
            modCount++;
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
            E oldValue = elementData(index);
    
            int numMoved = elementCount - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--elementCount] = null; // Let gc do its work
    
            return oldValue;
        }
    
        /**
         * Removes all of the elements from this Vector.  The Vector will
         * be empty after this call returns (unless it throws an exception).
         *
         * @since 1.2
         */
        public void clear() {
            removeAllElements();
        }
    
        // Bulk Operations
    
        /**
         * Returns true if this Vector contains all of the elements in the
         * specified Collection.
         *
         * @param   c a collection whose elements will be tested for containment
         *          in this Vector
         * @return true if this Vector contains all of the elements in the
         *         specified collection
         * @throws NullPointerException if the specified collection is null
         */
        public synchronized boolean containsAll(Collection<?> c) {
            return super.containsAll(c);
        }
    
        /**
         * Appends all of the elements in the specified Collection to the end of
         * this Vector, in the order that they are returned by the specified
         * Collection's Iterator.  The behavior of this operation is undefined if
         * the specified Collection is modified while the operation is in progress.
         * (This implies that the behavior of this call is undefined if the
         * specified Collection is this Vector, and this Vector is nonempty.)
         *
         * @param c elements to be inserted into this Vector
         * @return {@code true} if this Vector changed as a result of the call
         * @throws NullPointerException if the specified collection is null
         * @since 1.2
         */
        public synchronized boolean addAll(Collection<? extends E> c) {
            modCount++;
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityHelper(elementCount + numNew);
            System.arraycopy(a, 0, elementData, elementCount, numNew);
            elementCount += numNew;
            return numNew != 0;
        }
    
        /**
         * Removes from this Vector all of its elements that are contained in the
         * specified Collection.
         *
         * @param c a collection of elements to be removed from the Vector
         * @return true if this Vector changed as a result of the call
         * @throws ClassCastException if the types of one or more elements
         *         in this vector are incompatible with the specified
         *         collection
         * (<a href="Collection.html#optional-restrictions">optional</a>)
         * @throws NullPointerException if this vector contains one or more null
         *         elements and the specified collection does not support null
         *         elements
         * (<a href="Collection.html#optional-restrictions">optional</a>),
         *         or if the specified collection is null
         * @since 1.2
         */
        //求原集合与集合c的差集
        public synchronized boolean removeAll(Collection<?> c) {
            return super.removeAll(c);
        }
    
        /**
         * Retains only the elements in this Vector that are contained in the
         * specified Collection.  In other words, removes from this Vector all
         * of its elements that are not contained in the specified Collection.
         *
         * @param c a collection of elements to be retained in this Vector
         *          (all other elements are removed)
         * @return true if this Vector changed as a result of the call
         * @throws ClassCastException if the types of one or more elements
         *         in this vector are incompatible with the specified
         *         collection
         * (<a href="Collection.html#optional-restrictions">optional</a>)
         * @throws NullPointerException if this vector contains one or more null
         *         elements and the specified collection does not support null
         *         elements
         *         (<a href="Collection.html#optional-restrictions">optional</a>),
         *         or if the specified collection is null
         * @since 1.2
         */
         //求原集合与集合c的交集
        public synchronized boolean retainAll(Collection<?> c) {
            return super.retainAll(c);
        }
    
        /**
         * Inserts all of the elements in the specified Collection into this
         * Vector at the specified position.  Shifts the element currently at
         * that position (if any) and any subsequent elements to the right
         * (increases their indices).  The new elements will appear in the Vector
         * in the order that they are returned by the specified Collection's
         * iterator.
         *
         * @param index index at which to insert the first element from the
         *              specified collection
         * @param c elements to be inserted into this Vector
         * @return {@code true} if this Vector changed as a result of the call
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index > size()})
         * @throws NullPointerException if the specified collection is null
         * @since 1.2
         */
        public synchronized boolean addAll(int index, Collection<? extends E> c) {
            modCount++;
            if (index < 0 || index > elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityHelper(elementCount + numNew);
    
            int numMoved = elementCount - index;
            if (numMoved > 0)
                System.arraycopy(elementData, index, elementData, index + numNew,
                                 numMoved);
    
            System.arraycopy(a, 0, elementData, index, numNew);
            elementCount += numNew;
            return numNew != 0;
        }
    
        /**
         * Compares the specified Object with this Vector for equality.  Returns
         * true if and only if the specified Object is also a List, both Lists
         * have the same size, and all corresponding pairs of elements in the two
         * Lists are <em>equal</em>.  (Two elements {@code e1} and
         * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
         * e1.equals(e2))}.)  In other words, two Lists are defined to be
         * equal if they contain the same elements in the same order.
         *
         * @param o the Object to be compared for equality with this Vector
         * @return true if the specified Object is equal to this Vector
         */
        public synchronized boolean equals(Object o) {
            return super.equals(o);
        }
    
        /**
         * Returns the hash code value for this Vector.
         */
        public synchronized int hashCode() {
            return super.hashCode();
        }
    
        /**
         * Returns a string representation of this Vector, containing
         * the String representation of each element.
         */
        public synchronized String toString() {
            return super.toString();
        }
    
        /**
         * Returns a view of the portion of this List between fromIndex,
         * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
         * equal, the returned List is empty.)  The returned List is backed by this
         * List, so changes in the returned List are reflected in this List, and
         * vice-versa.  The returned List supports all of the optional List
         * operations supported by this List.
         *
         * <p>This method eliminates the need for explicit range operations (of
         * the sort that commonly exist for arrays).  Any operation that expects
         * a List can be used as a range operation by operating on a subList view
         * instead of a whole List.  For example, the following idiom
         * removes a range of elements from a List:
         * <pre>
         *      list.subList(from, to).clear();
         * </pre>
         * Similar idioms may be constructed for indexOf and lastIndexOf,
         * and all of the algorithms in the Collections class can be applied to
         * a subList.
         *
         * <p>The semantics of the List returned by this method become undefined if
         * the backing list (i.e., this List) is <i>structurally modified</i> in
         * any way other than via the returned List.  (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.)
         *
         * @param fromIndex low endpoint (inclusive) of the subList
         * @param toIndex high endpoint (exclusive) of the subList
         * @return a view of the specified range within this List
         * @throws IndexOutOfBoundsException if an endpoint index value is out of range
         *         {@code (fromIndex < 0 || toIndex > size)}
         * @throws IllegalArgumentException if the endpoint indices are out of order
         *         {@code (fromIndex > toIndex)}
         */
        //返回原集合的子集合,对子集合的修改直接反映在原集合上,且由于子集合被Collections.SynchronizedList包装,子集合也是线程安全的
        public synchronized List<E> subList(int fromIndex, int toIndex) {
            return Collections.synchronizedList(super.subList(fromIndex, toIndex),
                                                this);
        }
    
        /**
         * Removes from this list all of the elements whose index is between
         * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
         * Shifts any succeeding elements to the left (reduces their index).
         * This call shortens the list by {@code (toIndex - fromIndex)} elements.
         * (If {@code toIndex==fromIndex}, this operation has no effect.)
         */
        protected synchronized void removeRange(int fromIndex, int toIndex) {
            modCount++;
            int numMoved = elementCount - toIndex;
            System.arraycopy(elementData, toIndex, elementData, fromIndex,
                             numMoved);
    
            // Let gc do its work
            int newElementCount = elementCount - (toIndex-fromIndex);
            while (elementCount != newElementCount)
                elementData[--elementCount] = null;
        }
    
        /**
         * Loads a {@code Vector} instance from a stream
         * (that is, deserializes it).
         * This method performs checks to ensure the consistency
         * of the fields.
         *
         * @param in the stream
         * @throws java.io.IOException if an I/O error occurs
         * @throws ClassNotFoundException if the stream contains data
         *         of a non-existing class
         */
        private void readObject(ObjectInputStream in)
                throws IOException, ClassNotFoundException {
            ObjectInputStream.GetField gfields = in.readFields();
            int count = gfields.get("elementCount", 0);
            Object[] data = (Object[])gfields.get("elementData", null);
            if (count < 0 || data == null || count > data.length) {
                throw new StreamCorruptedException("Inconsistent vector internals");
            }
            elementCount = count;
            elementData = data.clone();
        }
    
        /**
         * Save the state of the {@code Vector} instance to a stream (that
         * is, serialize it).
         * This method performs synchronization to ensure the consistency
         * of the serialized data.
         */
        private void writeObject(java.io.ObjectOutputStream s)
                throws java.io.IOException {
            final java.io.ObjectOutputStream.PutField fields = s.putFields();
            final Object[] data;
            synchronized (this) {
                fields.put("capacityIncrement", capacityIncrement);
                fields.put("elementCount", elementCount);
                data = elementData.clone();
            }
            fields.put("elementData", data);
            s.writeFields();
        }
    
        /**
         * Returns a list iterator over the elements in this list (in proper
         * sequence), starting at the specified position in the list.
         * The specified index indicates the first element that would be
         * returned by an initial call to {@link ListIterator#next next}.
         * An initial call to {@link ListIterator#previous previous} would
         * return the element with the specified index minus one.
         *
         * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
         *
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        //返回双端迭代器
        public synchronized ListIterator<E> listIterator(int index) {
            if (index < 0 || index > elementCount)
                throw new IndexOutOfBoundsException("Index: "+index);
            return new ListItr(index);
        }
    
        /**
         * Returns a list iterator over the elements in this list (in proper
         * sequence).
         *
         * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
         *
         * @see #listIterator(int)
         */
        public synchronized ListIterator<E> listIterator() {
            return new ListItr(0);
        }
    
        /**
         * Returns an iterator over the elements in this list in proper sequence.
         *
         * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
         *
         * @return an iterator over the elements in this list in proper sequence
         */
        //返回顺序单向迭代器
        public synchronized 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
            int expectedModCount = modCount;
    
            public boolean hasNext() {
                // Racy but within spec, since modifications are checked
                // within or after synchronization in next/previous
                return cursor != elementCount;
            }
    
            public E next() {
                synchronized (Vector.this) {
                    checkForComodification();
                    int i = cursor;
                    if (i >= elementCount)
                        throw new NoSuchElementException();
                    cursor = i + 1;
                    return elementData(lastRet = i);
                }
            }
    
            public void remove() {
                if (lastRet == -1)
                    throw new IllegalStateException();
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.remove(lastRet);
                    expectedModCount = modCount;
                }
                cursor = lastRet;
                lastRet = -1;
            }
    
            @Override
            public void forEachRemaining(Consumer<? super E> action) {
                Objects.requireNonNull(action);
                synchronized (Vector.this) {
                    final int size = elementCount;
                    int i = cursor;
                    if (i >= size) {
                        return;
                    }
            @SuppressWarnings("unchecked")
                    final E[] elementData = (E[]) Vector.this.elementData;
                    if (i >= elementData.length) {
                        throw new ConcurrentModificationException();
                    }
                    while (i != size && modCount == expectedModCount) {
                        action.accept(elementData[i++]);
                    }
                    // update once at end of iteration to reduce heap write traffic
                    cursor = i;
                    lastRet = i - 1;
                    checkForComodification();
                }
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    
        /**
         * An optimized version of AbstractList.ListItr
         */
        final class ListItr extends Itr implements ListIterator<E> {
            ListItr(int index) {
                super();
                cursor = index;
            }
    
            public boolean hasPrevious() {
                return cursor != 0;
            }
    
            public int nextIndex() {
                return cursor;
            }
    
            public int previousIndex() {
                return cursor - 1;
            }
    
            public E previous() {
                synchronized (Vector.this) {
                    checkForComodification();
                    int i = cursor - 1;
                    if (i < 0)
                        throw new NoSuchElementException();
                    cursor = i;
                    return elementData(lastRet = i);
                }
            }
    
            public void set(E e) {
                if (lastRet == -1)
                    throw new IllegalStateException();
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.set(lastRet, e);
                }
            }
    
            public void add(E e) {
                int i = cursor;
                synchronized (Vector.this) {
                    checkForComodification();
                    Vector.this.add(i, e);
                    expectedModCount = modCount;
                }
                cursor = i + 1;
                lastRet = -1;
            }
        }
    
        @Override
        public synchronized void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int expectedModCount = modCount;
            @SuppressWarnings("unchecked")
            final E[] elementData = (E[]) this.elementData;
            final int elementCount = this.elementCount;
            for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
                action.accept(elementData[i]);
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
        //按条件删除
        @Override
        @SuppressWarnings("unchecked")
        public synchronized boolean removeIf(Predicate<? super E> filter) {
            Objects.requireNonNull(filter);
            // figure out which elements are to be removed
            // any exception thrown from the filter predicate at this stage
            // will leave the collection unmodified
            int removeCount = 0;
            final int size = elementCount;
            final BitSet removeSet = new BitSet(size);
            final int expectedModCount = modCount;
            for (int i=0; modCount == expectedModCount && i < size; i++) {
                @SuppressWarnings("unchecked")
                final E element = (E) elementData[i];
                if (filter.test(element)) {
                    removeSet.set(i);
                    removeCount++;
                }
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
    
            // shift surviving elements left over the spaces left by removed elements
            final boolean anyToRemove = removeCount > 0;
            if (anyToRemove) {
                final int newSize = size - removeCount;
                for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
                    i = removeSet.nextClearBit(i);
                    elementData[j] = elementData[i];
                }
                for (int k=newSize; k < size; k++) {
                    elementData[k] = null;  // Let gc do its work
                }
                elementCount = newSize;
                if (modCount != expectedModCount) {
                    throw new ConcurrentModificationException();
                }
                modCount++;
            }
    
            return anyToRemove;
        }
        //替换符合operator条件的所有元素
        @Override
        @SuppressWarnings("unchecked")
        public synchronized void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(operator);
            final int expectedModCount = modCount;
            final int size = elementCount;
            for (int i=0; modCount == expectedModCount && i < size; i++) {
                elementData[i] = operator.apply((E) elementData[i]);
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            modCount++;
        }
        //按c规则排序
        @SuppressWarnings("unchecked")
        @Override
        public synchronized void sort(Comparator<? super E> c) {
            final int expectedModCount = modCount;
            Arrays.sort((E[]) elementData, 0, elementCount, c);
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            modCount++;
        }
    
        /**
         * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
         * and <em>fail-fast</em> {@link Spliterator} over the elements in this
         * list.
         *
         * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
         * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
         * Overriding implementations should document the reporting of additional
         * characteristic values.
         *
         * @return a {@code Spliterator} over the elements in this list
         * @since 1.8
         */
        @Override
        public Spliterator<E> spliterator() {
            return new VectorSpliterator<>(this, null, 0, -1, 0);
        }
    
        /** Similar to ArrayList Spliterator */
        static final class VectorSpliterator<E> implements Spliterator<E> {
            private final Vector<E> list;
            private Object[] array;
            private int index; // current index, modified on advance/split
            private int fence; // -1 until used; then one past last index
            private int expectedModCount; // initialized when fence set
    
            /** Create new spliterator covering the given  range */
            VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
                              int expectedModCount) {
                this.list = list;
                this.array = array;
                this.index = origin;
                this.fence = fence;
                this.expectedModCount = expectedModCount;
            }
    
            private int getFence() { // initialize on first use
                int hi;
                if ((hi = fence) < 0) {
                    synchronized(list) {
                        array = list.elementData;
                        expectedModCount = list.modCount;
                        hi = fence = list.elementCount;
                    }
                }
                return hi;
            }
    
            public Spliterator<E> trySplit() {
                int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
                return (lo >= mid) ? null :
                    new VectorSpliterator<E>(list, array, lo, index = mid,
                                             expectedModCount);
            }
    
            @SuppressWarnings("unchecked")
            public boolean tryAdvance(Consumer<? super E> action) {
                int i;
                if (action == null)
                    throw new NullPointerException();
                if (getFence() > (i = index)) {
                    index = i + 1;
                    action.accept((E)array[i]);
                    if (list.modCount != expectedModCount)
                        throw new ConcurrentModificationException();
                    return true;
                }
                return false;
            }
    
            @SuppressWarnings("unchecked")
            public void forEachRemaining(Consumer<? super E> action) {
                int i, hi; // hoist accesses and checks from loop
                Vector<E> lst; Object[] a;
                if (action == null)
                    throw new NullPointerException();
                if ((lst = list) != null) {
                    if ((hi = fence) < 0) {
                        synchronized(lst) {
                            expectedModCount = lst.modCount;
                            a = array = lst.elementData;
                            hi = fence = lst.elementCount;
                        }
                    }
                    else
                        a = array;
                    if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
                        while (i < hi)
                            action.accept((E) a[i++]);
                        if (lst.modCount == expectedModCount)
                            return;
                    }
                }
                throw new ConcurrentModificationException();
            }
    
            public long estimateSize() {
                return (long) (getFence() - index);
            }
    
            public int characteristics() {
                return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
            }
        }
    }
    
    

    4. API 总结

    5. Vector使用示例

    作为线程安全的列表

    
    
    
    

    java8新特性

    
    
    
    

    6. 面试session

    • 谈谈Vector的扩容机制?

    Vector扩容机制分为两种情况:一种扩容机制由我们自定义每次扩多少容量,另一种每次扩容后的新容量为原容量的2倍。参见grow扩容函数:

        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //如果在初始化Vector使用public Vector(int initialCapacity, int capacityIncrement) 这种构造函数,会指定capacityIncrement每次新增的容量
             //否则,新容量 = 老容量 * 2
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
    • 谈谈Vector和ArrayList的异同?
      相同点:都是动态自动扩容的列表,数据结构都是数组。大部分API都是相同的;
      不同点:1. Vector是线程安全的,ArrayList是非线程安全的;2. 扩容机制不同:简单地讲,ArrayList每次扩容机制是 扩容后的新容量为原容量的1.5倍,而Vector扩容机制分为两种情况:
      一种扩容机制由我们自定义每次扩多少容量,另一种每次扩容后的新容量为原容量的2倍。3。讲一个API层面,Vector可以得到当前列表容量和size,ArrayList只可以得到当前size而不知容量。

    • 既然Vector都是线程安全的类了,迭代的时候还是运行fail-fast机制是否多余?
      不多余,虽有在得到迭代器的函数加入synchronized,但在迭代过程中,我们还可以使用Vector类的其他函数(不是迭代器类中包含的函数,如remove add)来修改列表结构,尽管这是单线程的,仍然会抛异常。这也是fail-fast机制,这是符合迭代器涉及原则的,“你决定用迭代器处理列表了,那下面所有的操作都让迭代器类的函数来接手吧”。如增加 删除等操作,使用迭代器类外Vector本身自带的修改列表结构的函数,都会报错。这种场景就像各位的女朋友,既然你选择了它,牵着它的手逛马路,望下别的女孩子,它也会“情绪异常”,逃~

    来些例子

    import java.util.*;
    public class VectorTest {
        public static void main(String[] args) {
            Vector<Integer> vector = new Vector<>();
            vector.addAll(Arrays.asList(2,3,9,4,5));
            Iterator<Integer> iterator = vector.iterator(); //握住女朋友的手狂街
            vector.add(100);//望了一下别的漂亮姐姐,也不介意多一个
            while (iterator.hasNext()) {
                int grilfriendbomb = iterator.next(); //女朋友立即发现你在看漂亮姐姐,女朋友立即炸了。
                System.out.println(grilfriendbomb); //你早死了
            }
        }
    }
    
    • 结果
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.Vector$Itr.checkForComodification(Vector.java:1210)
    	at java.util.Vector$Itr.next(Vector.java:1163)
    	at collectionlearn.VectorTest.main(VectorTest.java:10)
    

    虽然编了个段子,希望足够引起大家注意:迭代器“占有欲”很强,"很会吃醋",既然选择了它,请坚定的使用它。ArrayList在单线程环境中同样也存在这个问题。总之,如果使用迭代器,请务必坚定的使用它!

    package collectionlearn;
    
    import java.util.*;
    
    public class VectorTest {
        public static void main(String[] args) {
            Vector<Integer> vector = new Vector<>();
            vector.addAll(Arrays.asList(2,3,9,4,5));
            System.out.println(vector);
            ListIterator<Integer> itr = vector.listIterator(); //握住女朋友的手狂街
            itr.next();
            itr.add(1); //女朋友被猝不及防的亲了一口,使用迭代器类函数修改列表
            while (itr.hasPrevious()) {
                int grilhhh = itr.previous(); //女朋友哈哈哈
                System.out.print(grilhhh+" "); //给你笑
            }
            System.out.println();
            while (itr.hasNext()) {
                int gg  = itr.next();
                System.out.print(gg +" ");
            }
        }
    }
    
    
    • 结果
    [2, 3, 9, 4, 5]
    1 2 
    2 1 3 9 4 5 
    Process finished with exit code 0
    
    • 被迭代器掏空
    package collectionlearn;
    import java.util.*;
    public class VectorTest {
        public static void main(String[] args) {
            Vector<Integer> vector = new Vector<>();
            vector.addAll(Arrays.asList(2,3,9,4,5));
            System.out.println("没有女朋友的时候:" + vector);
            Iterator<Integer> iterator = vector.iterator(); //握住女朋友的手狂街
            while (iterator.hasNext()) {
                int stand = iterator.next();
                iterator.remove();//女朋友开始掏空你
                System.out.print(stand + " ");
            }
            System.out.println();
            System.out.println("啊,这谁顶得住呀:" + vector);//被女朋友掏空
    
        }
    }
    
    
    • 结果
    没有女朋友的时候:[2, 3, 9, 4, 5]
    2 3 9 4 5 
    啊,这谁顶得住呀:[]
    
    • 出去大保健
    package collectionlearn;
    import java.util.*;
    public class VectorTest {
        public static void main(String[] args) {
            Vector<Integer> vector = new Vector<>();
            vector.addAll(Arrays.asList(2,3,9,4,5));
            System.out.println("没有女朋友的时候:" + vector);
            Iterator<Integer> iterator = vector.iterator(); //找到女朋友
            vector.remove(0); //出去大保健
            while (iterator.hasNext()) {
                int grilfriendbomb = iterator.next(); //立即捕捉到蛛丝马迹,女朋友炸了
                System.out.print(grilfriendbomb + " "); //你早死了
            }
        }
    }
    
    • 结果
    没有女朋友的时候:[2, 3, 9, 4, 5]
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.Vector$Itr.checkForComodification(Vector.java:1210)
    	at java.util.Vector$Itr.next(Vector.java:1163)
    	at collectionlearn.VectorTest.main(VectorTest.java:11)
    
    

    总结:迭代器就是一个”女朋友“,用它需谨慎。以上几个例子,证明了fail-fast不仅在多线程中提醒程序员,使用迭代器时候一定不要使用迭代器类以外的函数修改列表。fail-fast是迭代器尽最大努力监测列表结构是否被改变,通过当前迭代器实例来改变列表结构不会抛异常,否则会抛ConcurrentModificationException。特别低,for(:)语法糖本质就是Iterator迭代器,上述发生的异常在这个语法糖中更加隐蔽。

    package collectionlearn;
    import java.util.*;
    public class VectorTest {
        public static void main(String[] args) {
            Vector<Integer> vector = new Vector<>();
            vector.addAll(Arrays.asList(2,3,9,4,5));
            for (int i : vector){
                if(i==3) vector.remove((Object)3); //出去大保健,异地的女朋友立马都感应到,啊你死了
            }
            System.out.println(vector);
        }
    }
    
    
    • 结果
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.Vector$Itr.checkForComodification(Vector.java:1210)
    	at java.util.Vector$Itr.next(Vector.java:1163)
    	at collectionlearn.VectorTest.main(VectorTest.java:7)
    
  • 相关阅读:
    如何让一个浮动垂直居中:两种方式!带来效果~~~~~~
    rgba()和opacity之间的区别(面试题)
    常用浏览器内核!IE,Chrome ,Firefox,Safari,Opera 等内核
    有关Option.inSamplSize 和 Compress 图片压缩
    Android App 启动 Activity 创建解析
     (转)windows一台电脑添加多个git账号
    Handler向子线程发送数据
    Android Touch事件分发
    int 转十六进制
    JVM client模式和Server模式
  • 原文地址:https://www.cnblogs.com/ahpucd/p/13326889.html
Copyright © 2020-2023  润新知