您的位置:首页 > 编程语言 > Java开发

Vector源码解析(JDK1.8)

2019-07-24 15:58 267 查看

文档头

  • Vector是可变长度数组
  • 通过 capacity 和 capacityIncrement 管理数据的存储空间
  • 也是fast-fail的
  • 是同步的 

变量定义

  • [code]protected Object[] elementData; // 元素数组
  • [code]protected int elementCount; // 元素数量
  • [code]protected int capacityIncrement; // 容量增量, 增量<=0时 ,扩容时会两倍增长

构造方法

  • [code]    public Vector() {
    this(10); // 容量10, 增量0
    }
    public Vector(int initialCapacity) {
    this(initialCapacity, 0); // 增量0
    }
    public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
    throw new IllegalArgumentException("Illegal Capacity: "+
    initialCapacity);
    this.elementData = new Object[initialCapacity]; // 分配空间
    this.capacityIncrement = capacityIncrement; //
    }

    容量默认10,增量默认0。

重要方法

  1. [code]ensureCapacity(int minCapacity)  扩容
    [code]   public synchronized void ensureCapacity(int minCapacity) {
    if (minCapacity > 0) { // minCapacity大于0时,开始扩容
    modCount++;
    ensureCapacityHelper(minCapacity);
    }
    }
    private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    if (minCapacity - elementData.length > 0) // minCapacity > 当前长度时开始扩容
    grow(minCapacity);
    }
    private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length; // 获取原长度
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
    capacityIncrement : oldCapacity);  //
    // capacityIncrement > 0 时, 新容量为(原容量 + capacityIncrement); 否则原容量*2
    if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity; // 新容量 < minCapacity时,取minCapacity
    if (newCapacity - MAX_ARRAY_SIZE > 0)
    newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity); // 创建新数组, 复制
    }

    扩容过程:计算新容量 increment > 时为原容量 + increment,否则为原容量 * 2; 然后判断新容量与minCapacity较大值,赋给新容量; 按照新容量创建新数组。 注意ensureCapacity是同步方法。

  2. add(E e)  

    [code]    public synchronized boolean add(E e) {
    modCount++; // 增加modCount
    ensureCapacityHelper(elementCount + 1); // 确认容量
    elementData[elementCount++] = e; // 存储在末尾
    return true;
    }

    add(int index, E element) 

    [code]  public void add(int index, E element) {
    insertElementAt(element, index);
    }
    
    public synchronized void insertElementAt(E obj, int index) {
    modCount++; // 增加modCount
    if (index > elementCount) { // index越界判断
    throw new ArrayIndexOutOfBoundsException(index
    + " > " + elementCount);
    }
    ensureCapacityHelper(elementCount + 1);  // 确认容量
    System.arraycopy(elementData, index, elementData, index + 1, elementCount -
    index); // 将index开始的一起移动到index+1开始
    elementData[index] = obj; // 赋值
    elementCount++;
    }

    可以看到add操作和ArrayList几乎一样,,只是加了synchronized。

  3.  remove(int index) 

    [code]    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); // 将index+1后的移动到index,集体前移一格。
    elementData[--elementCount] = null; // 原来末尾置为null,减size。
    return oldValue;
    }

    remove(Object o) 

    [code] public boolean remove(Object o) {
    return removeElement(o);
    }
    public synchronized boolean removeElement(Object obj) {
    modCount++;
    int i = indexOf(obj); // 查询obj的偏移量
    if (i >= 0) {
    removeElementAt(i);
    return true;
    }
    return false;
    }
    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);
    }
    elementCount--;
    elementData[elementCount] = null; /* to let gc do its work */
    }

    也与ArrayList很相似,加上了synchronized。 通过复制数组实现,,addAll、removeAll也是复制数组实现。

  4. toArray() 与 toArray(T[] a) 与ArrayList一样,加上synchronized。

  5. Iterator()方法内next()与remove()加上synchronized。

总结

  1. vector内部用来大量的synchronized保证同步,是线程安全的List实现
  2. 通过capacity指定数组容量,capacityIncrement指定扩容增量。capacityIncrement<=0时,新容量为原来2被,否则新容量为(原容量 + capacityIncrement )。这并不是最后的容量,而是用新容量与指定的minCapacity比较,取较大值作为最后的新容量。
  3. 方法实现方式与ArrayList相同,只是加入了同步机制。
  4. 也实现了RandomAccess接口,遍历时用for(int i=0;i<sizeli++)会比iterator快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: