JDK14中Vector类的动态扩容简单介绍

JDK14中Vector类的动态扩容

Vector类的动态扩容

  • Vector与ArrayList一样,也是长度可变的动态数组。
  • ArrayList无参构造方法实际上是创建空数组,在第一次调用add()或addAll()时会扩容成长度为10;而Vector在调用无参构造方法时,就创建了一个长度为10的空数组。
  • 当集合中的元素数量大于当前集合的长度时,Vector会扩容为原来的2倍,而ArrayList只会扩容为原来的1.5倍。

源码分析

无参构造方法

  • 注意Vector在调用无参构造方法时,就创建了一个长度为10的空数组。
/**
 * Constructs an empty vector so that its internal data array
 * has size {@code 10} and its standard capacity increment is
 * zero.
 */
public Vector() {
    this(10);
}

扩容

  • 调用add()方法需要扩容时,前面的处理都和ArrayList动态扩容的方法相同,具体分析可以看这篇博客,直到grow()方法。
/**
 * Appends the specified element to the end of this Vector.
 *
 * @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++;
    add(e, elementData, elementCount);
    return true;
}

/**
 * This helper method split out from add(E) to keep method
 * bytecode size under 35 (the -XX:MaxInlineSize default value),
 * which helps when add(E) is called in a C1-compiled loop.
 */
private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    elementCount = s + 1;
}

private Object[] grow() {
    return grow(elementCount + 1);
}
  • grow()
    • capacityIncrement是增长因子。
    • 当增长因为大于0时,Vector会增加capacityIncrement的量;
    • 否则,Vector的容量加倍,即为原来的2倍。
/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 * @throws OutOfMemoryError if minCapacity is less than zero
 */
private Object[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = ArraysSupport.newLength(oldCapacity,
            minCapacity - oldCapacity, /* minimum growth */
            capacityIncrement > 0 ? capacityIncrement : oldCapacity
                                       /* preferred growth */);
    return elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
 * Calculates a new array length given an array's current length, a preferred
 * growth value, and a minimum growth value.  If the preferred growth value
 * is less than the minimum growth value, the minimum growth value is used in
 * its place.  If the sum of the current length and the preferred growth
 * value does not exceed {@link #MAX_ARRAY_LENGTH}, that sum is returned.
 * If the sum of the current length and the minimum growth value does not
 * exceed {@code MAX_ARRAY_LENGTH}, then {@code MAX_ARRAY_LENGTH} is returned.
 * If the sum does not overflow an int, then {@code Integer.MAX_VALUE} is
 * returned.  Otherwise, {@code OutOfMemoryError} is thrown.
 *
 * @param oldLength   current length of the array (must be non negative)
 * @param minGrowth   minimum required growth of the array length (must be
 *                    positive)
 * @param prefGrowth  preferred growth of the array length (ignored, if less
 *                    then {@code minGrowth})
 * @return the new length of the array
 * @throws OutOfMemoryError if increasing {@code oldLength} by
 *                    {@code minGrowth} overflows.
 */
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
    // assert oldLength >= 0
    // assert minGrowth > 0

    int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
    if (newLength - MAX_ARRAY_LENGTH <= 0) {
        return newLength;
    }
    return hugeLength(oldLength, minGrowth);
}

Vector类和ArrayList类的区别

  1. vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的;而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。
  2. 当集合中的元素数量大于当前集合的长度时,Vector会扩容为原来的2倍,而ArrayList只会扩容为原来的1.5倍。如果在集合中使用数据量比较大的数据,用vector有一定的优势。

JDK14中Vector类的动态扩容简单介绍

上一篇:剑桥雅思写作高分范文ESSAY37


下一篇:机器学习实战8-FP-growth