JDK源码

java.util.Vector源码解析

2018-02-27  本文已影响3人  sunpy

所属包

package java.util;

继承与实现关系

public class Vector<E>  
    extends AbstractList<E>  
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable  

准备知识

Vector集合实际上是实现了动态数组的方式,是可以随着向量元素的增加可以动态增长。实际上就是一种动态顺序表的应用。

属性

/**  
  * Object类型的数组,用来存储实际数据  
  */  
 protected Object[] elementData;  
  
 /**  
  * 代表向量中元素的个数  
  */  
 protected int elementCount;  
  
 /**  
  * 向量的增长因数  
  * 当向量的容量大于其容量时,向量的容量自动递增的量。  
  * 如果容量增量小于或等于零,则每次需要增长时,向量的容量增加一倍。  
  */  
 protected int capacityIncrement;

构造方法

  /**  构造方法1  
   * 输入参数为初始化容量和增量参数的构造方法  
   */  
  public Vector(int initialCapacity, int capacityIncrement) {  
      super();  
/如果向量初始化容量小于0,那么就报非法参数异常的错误。  
      if (initialCapacity < 0)  
          throw new IllegalArgumentException("Illegal Capacity: "+  
                                             initialCapacity);  
/将初始化容量的长度作为Object数组实际长度  
      this.elementData = new Object[initialCapacity];  
/初始化增量参数  
      this.capacityIncrement = capacityIncrement;  
  }  
 /** 构造方法2  
  * 使用指定的初始容量和等于零的容量增量构造一个空向量  
  */  
 public Vector(int initialCapacity) {  
     this(initialCapacity, 0);  
 }  
 /** 构造方法3  
  * 构造一个初始化容量为10,增量为0的向量  
  */  
 public Vector() {  
     this(10);  
 }  
   /** 构造方法4  
    * 构造一个包含指定集合中的元素的向量,这些元素按其集合的迭代器返回元素的顺序排列。  
    */  
   public Vector(Collection<? extends E> c) {  
//将集合Collection转化为Object数组elementData。如果c为空,那么就会报空指针异常  
       elementData = c.toArray();  
       elementCount = elementData.length;  
       //将c中的元素拷贝到elementData中  
       if (elementData.getClass() != Object[].class)  
           elementData = Arrays.copyOf(elementData, elementCount, Object[].class);  
   }  

方法

ensureCapacity方法:扩充容量

/**  
 * 增加此向量的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。  
 * 如果当前数组的容量小于minCapacity,那么就增加容量,增加数组长度  
 * 新数组的长度等于原数组的长度加上增量capacityIncrement。  
 * 如果增加capacityIncrement小于等于0,那么就自动扩增为原来二倍。  
 * 如果扩增为原来的二倍还是比minCapacity小,那么就将minCapacity作为Object数组的长度。  
 */  
  public synchronized void ensureCapacity(int minCapacity) {  
      if (minCapacity > 0) {  
          modCount++;  
          ensureCapacityHelper(minCapacity);  
      }  
  }  
private void ensureCapacityHelper(int minCapacity) {  
       //minCapacity为实际向量中的元素需要的容量,如果minCapacity大于当前数组长度,那么就进行扩容  
       if (minCapacity - elementData.length > 0)  
           grow(minCapacity);  
   }  
   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  
  
   private void grow(int minCapacity) {  
       //oldCapacity旧容量是Object数组的长度  
       int oldCapacity = elementData.length;  
//如果增量capacityIncrement大于0,那么新容量为旧容量加上增量,否则为旧容量的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);  
   }  
  
   private static int hugeCapacity(int minCapacity) {  
//如果实际需要的容量小于0就抛出异常  
       if (minCapacity < 0)   
           throw new OutOfMemoryError();  
//实际容量如果比最大容量还大,那么实际容量为Integer.MAX_VALUE,否则为Integer.MAX_VALUE - 8  
       return (minCapacity > MAX_ARRAY_SIZE) ?  
           Integer.MAX_VALUE :  
           MAX_ARRAY_SIZE;  
   }  

add方法

    /**  
     * 采用同步的方式往向量中添加元素e  
     */  
    public synchronized boolean add(E e) {  
        modCount++;  
        //由于添加元素需要动态的扩容,所以调用ensureCapacityHelper方法,长度要增长1  
        ensureCapacityHelper(elementCount + 1);  
        //这步采用顺序表添加元素的模板代码,赋值长度加1  
        elementData[elementCount++] = e;  
        return true;  
    }  

阅读总结

(1)Vector容器是线程安全的。
(2)Vector采用动态数组的方式实现的。
(3)如果向量元素数量大于旧Vector容器的容量,那么将旧容器扩容为原来的2倍。


---------------------------该源码为jdk1.7版本的

上一篇 下一篇

猜你喜欢

热点阅读