Java集合 Vector的底层详解

Java集合的 Vector底层讲解

Vector作为List的另外一个典型的实现类,完全支持List的全部功能,Vector的实现其实和ArrayList的底层实现很类似,都是封装了一个Object[],但Vector是一个比较古老的集合,JDK1.0就已经存在,建议不要使用这个集合,Vector与ArrayList的主要区别是:Vector是线程安全的,ArrayList是非线程安全的,但性能上Vector比ArrayList低。

基本属性

protected Object[] elementData;  //存放元素的数组
protected int elementCount;    //已经放入数组的元素个数
protected int capacityIncrement; //数组的增长系数

源码解析

package java.util;

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

    //定义数组,存放元素
    protected Object[] elementData;

    //已经放入数组的元素数量
    protected int elementCount;

    //增长的系数
    protected int capacityIncrement;

    //可序列化版本号
    private static final long serialVersionUID = -2767605614048989439L;

    //构造方法,提供初始大小,和增长系数
    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

    //构造方法,提供初始大小,增长系数为零
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

    //无参构造方法
    public Vector() {
        this(10);
    }

    //构造方法,将指定的集合元素转化为Vector
    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        //判断c.toArray是否是Object[]类型
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

    //将elementData中的元素全部拷贝到anArray数组中
    public synchronized void copyInto(Object[] anArray) {
        System.arraycopy(elementData, 0, anArray, 0, elementCount);
    }

    //将数组长度设置为等于vector的个数
    public synchronized void trimToSize() {
        modCount++;
        int oldCapacity = elementData.length;
        if (elementCount < oldCapacity) {
            elementData = Arrays.copyOf(elementData, elementCount);
        }
    }

    //扩充容量
    public synchronized void ensureCapacity(int minCapacity) {
        if (minCapacity > 0) {
            modCount++;
            ensureCapacityHelper(minCapacity);
        }
    }

    //扩充容量帮助函数
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        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 增加capacityIncrement个容量,否则容量扩充当前容量的一倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //扩容操作,生成已给新的数组,容量为newCapacity,并将elementData中的元素全部拷贝到新数组中,并将新生成的数组在赋值给elementData 
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  }

总结
Vector和ArrayList的底层实现方式非常的相近,官方说少使用Vector,还是尽量少使用,通过源码可以看出,每个方法都添加了synchronized关键字来保证同步,所以它是线程安全的,但是正是这些方法的同步,让其效率大大的降低了。比ArrayList的效率要慢

因此,给出以下几点总结:
1、Vector有四个不同的构造函数。 无参构造的容量默认值为10
2、扩充容量的方法ensureCapacityHelper。与ArrayList不同的是,Vector在每次增加元素(可能是1个,也可能是一组)时,都要调用该方法来确保足够的容量。当容量不足以容纳当前的元素个数时,就看构造方法中传入的容量增长系数CapacityIncrement是否为0,如果不为0,就设置新的容量为 旧容量 + 容量增长量;如果为0,设置新的容量为旧的容量的2倍,如果设置后的容量还不够,则直接新的容量设置为 旧容量 + 传入参数所需要的容量 而后同样用Arrays.copyof()方法将元素拷贝到新的数组。
3、很多方法都加入了synchronized同步语句,来确保线程安全。
4、Vector在查找给定元素索引值等方法中,源码都将该元素的值分为null和不为null两种情况处理,Vector中允许元素为null
5、其他很多地方与ArrayList实现大同小异,Vector现在已经不再使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值