容器-Vector容器类(四)

容器-Vector容器类(四)

  1. Vector底层也是用数组实现的,相关的方法都增加了同步检查,线程安全,效率低

    Vector容器类和ArrayList容器类的区别就是在线程,ArrayList是线程不安全的,效率高

    • Vector的添加元素,因为都是继承List接口,所以Vector类和ArrayList类的方法都是差不多的,要想了解更多的方法,直接参照Array-list类。
    public class VectorTest {
          
          
        public static void main(String[] args) {
          
          
    
            //实例化Vector
            List<String> v=new Vector<>();
            v.add("a");
            v.add("b");
            v.add("c");
    
            for (int i=0;i<v.size();i++){
          
          
                System.out.println(v.get(i));
            }
            System.out.println("--------------------");
            for (String str:v){
          
          
                System.out.println(str);
            }
        }
    }
    
    
  2. Vector的源码分析,在JDK1.8之后,Vector和ArryList的区别就是

    • 第一,ArryList在创建一个数组长度为10的数组,采用的是延时的初始化,而Vector采用的是立即初始化

    • 第二,ArryList是以1.5倍在扩容,而Vector是以2倍在扩容

    • 先建立一个Vector对象,用Ctrl+鼠标右键进入源代码

      public class VectorTest {
              
              
          public static void main(String[] args) {
              
              
      
              //实例化Vector
              List<String> v=new Vector<>();//Vector对象,用Ctrl+鼠标右键进入源代码
              v.add("a");
              v.add("b");
              v.add("c");
      
              for (int i=0;i<v.size();i++){
              
              
                  System.out.println(v.get(i));
              }
              System.out.println("--------------------");
              for (String str:v){
              
              
                  System.out.println(str);
              }
          }
      }
      
    • Vector的结构和成员变量

      public class Vector<E>//继承了AbstractList<E>抽象类,实现了List<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
           */
          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;//计算容量增长,没给初始化就是0
      
          /** 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
           */
      
    • 然后,我们看无参构造方法

         /**
           * Constructs an empty vector so that its internal data array
           * has size {@code 10} and its standard capacity increment is
           * zero.
           */
          public Vector() {
              
              //没有指定长度,都是默认10的
              this(10);
          }
      
    • 继续看this这个构造方法

      /**
           * 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);//initialCapacity的值是10,capacityIncrement是0
          }
      
    • 在继续this,看这个构造方法

       /**
           * 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) {
              
              
              //initialCapacity是10
              super();
              if (initialCapacity < 0)//initialCapacity是10,不执行这个条件
                  throw new IllegalArgumentException("Illegal Capacity: "+
                                                     initialCapacity);
              this.elementData = new Object[initialCapacity];
              //初始化之后,nitialCapacity是10,就是一个数组为10的长度,赋值给elementData=10,所以这就是立即初始化的方式。  
              this.capacityIncrement = capacityIncrement;// capacityIncrement还是0
          }
      
  3. 用add的方法添加元素

    • 用Ctrl+鼠标左键进入源代码
    boolean add(E e);
    
    • 用Ctrl+Alt+鼠标左键,选择Vector类的add方法

      boolean add(E e);
      
    • Vector类的add方法的源码

      /**
           * 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) {
              
              //synchronized这就它解决线程安全的,把并行化的方式改成串行画的方式
              modCount++;//跟ArrayList的那个相似的计时器
              ensureCapacityHelper(elementCount + 1);//判断是否需要扩容的方法
              elementData[elementCount++] = e;
              return true;
          }
      
      
    • 什么时候会扩容,我们看下ensureCapacityHelpe的方法

        /**
           * 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)
           */
          private void ensureCapacityHelper(int minCapacity) {
              
              //minCapacity现在是10,当你变成11的时候,就会满足下面的条件minCapacity - elementData.length=11-10=1>0,进行扩容
              // overflow-conscious code
              if (minCapacity - elementData.length > 0)//触发是否扩容的条件
                  grow(minCapacity);
          }
      
      
    • 假设minCapacity是11了,怎么扩容,grow(int minCapacity)是扩容的方法

      private void grow(int minCapacity) {
              
              //minCapacity是11
          // overflow-conscious code
          int oldCapacity = elementData.length;
          //elementData.length是10,所以oldCapacity是10
          int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                           capacityIncrement : oldCapacity);
          //根据三目运算符来,capacityIncrement是0,0不会大于0,执行oldCapacity,所以oldCapacity是10,所以newCapacity=10+10=20
          if (newCapacity - minCapacity < 0)  //20-11大于0不执行
              newCapacity = minCapacity;
          if (newCapacity - MAX_ARRAY_SIZE > 0)//也是不会执行的
              newCapacity = hugeCapacity(minCapacity);
          elementData = Arrays.copyOf(elementData, newCapacity);
          //就来最重要的了,elementData是10,newCapacity是20,经过copyOf之后,elementData就会变成20,就实现了扩容。
          //minCapacity时21时,oldCapacity是20, newCapacity=20+20=40,经过copyOf之后,elementData就变成了40
          //所以也就是已2倍扩容了
      }
      

猜你喜欢

转载自blog.csdn.net/Xun_independent/article/details/114674312