深入理解Vector源码


我们还是先从继承实现关系来看一下Vector的前世今生

Vector和ArrayList一样,是基于数组实现的List,那二者的区别又是什么呢?

在前面讲ArrayList的时候,我们知道它是线程不安全的,那么世代追求“高可用,高并发,高性能”的IT人必然不会视而不管,同时ArrayList的高效率又是我们所需要的,因此Vector就诞生了。

接下来我们从源码中看一下它是如何实现的

壹·相关变量

 /**
     * 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;

    /**
     *这个{@code Vector}对象中有效组件的数量
     * Components {@code elementData[0]} through
     * {@code elementData[elementCount-1]} are the actual items.
     *
     * @serial
     */
    protected int elementCount;

    /**
     * 当向量的大小大于其容量时,其容量自动增加的数量。如果容量增量小于或等于零,则每次需要增加时,
     * 向量的容量将加倍。
     * capacityIncrement 是动态数组的增长系数,你也可以理解为增量。如果在创建Vector时,
     * 指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时,
     * 增加的大小都是capacityIncrement。
     * 
     * @serial
     */
    protected int capacityIncrement;

    /** 使用JDK 1.0.2中的serialVersionUID实现互操作性 */
    private static final long serialVersionUID = -2767605614048989439L;

贰·相关构造方法

    /**
     * 构造一个空vector,具有指定的初始容量和容量增量。
     *
     * @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   vector的初始容量
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

    /**
     * 构造一个空向量,使其内部数据数组的大小为{@code 10},其标准容量增量为零。
     */
    public Vector() {
        this(10);
    }
    /**
     * 按照集合迭代器返回元素的顺序构造一个vector,其中包含指定集合的元素。
     *
     * @param c the collection whose elements are to be placed into this
     *       vector
     * @throws NullPointerException if the specified collection is null
     * @since   1.2
     */
    public Vector(Collection<? extends E> c) {
    //注意此时使用了toArray方法,如果elementData为空的话,则会抛出异常
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        //下面则完成对集合元素的添加,如果 c 是 ArrayList 的话,则直接完成赋值,否则的话使用
        //Arrays 的copy 方法
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

叁·CURD的实现

增加

/**
 * 添加特定的元素到Vector的尾部,需要注意的是这个方法是synchronized
 * @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++;
    // 保证容量,这个就是在添加元素之前要要保证内部的数组大小足够可以容纳该元素,在ArrayList 里面也有,是这样的  ensureCapacityInternal(size + 1),(elementCount + 1) 可以认为是需要的
    ensureCapacityHelper(elementCount + 1);
    // 容量可以保证之后,我们就将这个元素添加到数组的指定位置
    elementData[elementCount++] = e;
    return true;
}

ensureCapacityHelper:

    /**
     * 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) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

grow:

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

这和ArrayList的扩容机制一样,在之前已经讲解过了,这里就不再多解释

在指定地方增加

    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++;
    }

get:

/**
* 返回Vector中特定位置的的元素(需要注意的是这个方法,依然是加了synchronized 修饰的)
* @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
*/
public synchronized E get(int index) {
   //  如果index >= elementCount 则抛出异常,因为最后一个元素是elementData[elementCount-1]
   if (index >= elementCount)
       throw new ArrayIndexOutOfBoundsException(index);

   return elementData(index);
}
/**
* 返回特定的数据
*/
@SuppressWarnings("unchecked")
E elementData(int index) {
   return (E) elementData[index];
}

遍历:

通过迭代器遍历:

Integer value = null;
Iterator<int> size = vec.iterator();
while(size.hasNext()){
value = size.next();
}

随机遍历,通过索引值:

Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
    value = (Integer)vec.get(i);        
}

For循环:

Integer value = null;
for (Integer integ:vec) {
    value = integ;
}

Enumeration遍历:

Integer value = null;
Enumeration enu = vec.elements();
while (enu.hasMoreElements()) {
    value = (Integer)enu.nextElement();
}

肆·对比ArrayList

  • Vector和ArrayList都是属于List家族的,其区别在于线程安全上
  • Vector 实现线程安全的方式就是给方法上加synchronized
  • 线程安全的情况下大多使用ArrayList,多线程的情况下使用Vector
  • Vector 扩容的后的容量不是当前容量加上capacityIncrement就是当前容量的2倍,而ArrayList是1.5倍
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值