java基础:Vector/Stack — 源码分析

1,095 阅读2分钟

其他更多java基础文章:
java基础学习(目录)


概述

虽然,Vector和Stack在我们的编程中,使用的比较少,至少我使用的比较少,一般情况下,我都是倾向于使用List来存储一些同类型的元素。
Vector的内部实现和ArrayList的内部实现基本一致,内部都是借助于数组来实现的,主要区别是方法加了synchronized关键字,实现了线程安全。
Stack是继承自Vector来实现的,而且Stack只是在Vector的基础上提供了几个方法罢了,就不展开讲解了。

Vector

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

Vector继承了AbstractList抽象类并实现了List、RandomAccess、Cloneable、Serializable接口,和ArrayList一样。

基础字段

    protected Object[] elementData;
    protected int elementCount;
    protected int capacityIncrement;
  • elementData:数组,用来存放元素的
  • elementCount:记录数组中已经保存了的数据的个数
  • capacityIncrement:自动扩容的大小,即当数组满了之后,就添加capacityIncrement个空间装载元素,如果capacityIncrement<=0,则扩容时就扩容到目前Vector容量的两倍

方法细节

add方法

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    
    //在指定位置添加元素
    public void add(int index, E element) {
        insertElementAt(element, index);
    }

    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++;
    }
    
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        //当数组已满,则调用grow函数来对数组进行扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //扩容的大小由capacityIncrement决定,如果capacityIncrement<=0,则扩容到目前数组的两倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        //检查是否newCapacity溢出了
        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) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

基本没什么难度,增加了synchronized关键字,实现了线程安全,其他跟ArrayList的基本一样。可以参考java基础:ArrayList — 源码分析
唯一有点不同的是,Vector的扩容默认是扩容为2倍,若capacityIncrement不为0,则扩容capacityIncrement的值。ArrayList则是扩容为1.5倍。

总结

  1. Vector是基于数组来实现的
  2. Vector是线程安全的,ArrayList是线程不安全的。
  3. Vector实现基本与ArrayList一样