Java集合框架 —— Vector

 2023-01-30
原文作者:蒋先森 原文地址:https://jlj98.top/

声明:本文使用JDK1.8

关于ArrayList和LinkedList的区别可以看这里。

Vector

Vector也是实现List接口的,底层数据结构和 ArrayList 类似,也是一个动态数组存放数据。不过是在 add() 方法的时候使用 synchronize 进行同步写数据,但是开销较大,所以 Vector 是一个同步容器并不是一个并发容器。

初始化

Vector也提供了几种初始化方法,默认初始化为10。

    //initialCapacity 初始容量;capacityIncrement 每次扩容时的增加量
    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);
    }

add方法

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1); //调用ensureCapacityHelper 方法,是否需要扩容
        elementData[elementCount++] = e;
        return true;
    }
    
    //参数 minCapacity 当前集合的位置加一
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

指定位置插入

    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);
        //这是一个native方法,数组指定位置往后移动一位
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
        elementData[index] = obj;//覆盖指定位置的值
        elementCount++;//数组大小统计加一
    }

扩容

Vector默认情况下每次扩容请求其大小的2倍空间。这和初始化时 capacityIncrement 的值有关,如果不为0,则是老的容量在加上 capacityIncrement。最后和你现在需要的容量在进行对比,是否符合当前需要的容量。ArrayList 默认扩容1.5。

    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;
        //如果扩容增加量不为零,每次的扩容是加上扩容量,不然则是原来的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) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }