package com.example.demo.test;
import java.util.Vector;
/**
* <p>
* <code>VectorTest</code>
* </p>
* Description: JDK 1.8
* 测试Vector的扩容方式,通过测试可以看出其每次以2的倍数形式扩充Object数组
*
* @author Jalen
* @date 2019/8/27 13:31
*/
public class VectorTest {
public static void main(String[] args) {
createEmptyVector();
}
/**
* 创建Vector
* 调用链1(初始化):
* {@link java.util.Vector#Vector(int)}
* 传入capacity为2,如果为空,默认capacity是10
* {@link java.util.Vector#Vector(int, int)}
* 第一个参数为初始容量initialCapacity,为2,第二个参数是capacityIncrement,默认在初始化时传0
* 该操作创建一个2个长度的Object数组,且capacityIncrement赋值为0
* 代码:
* super();
* if (initialCapacity < 0)
* throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
* this.elementData = new Object[initialCapacity];
* this.capacityIncrement = capacityIncrement;
* 调用链2:
* {@link java.util.Vector#add(Object)}
* synchronized修饰,modCount自增,计算容量(如果不够会执行扩容),根据下标为elementData赋值
* 代码:
* modCount++;
* ensureCapacityHelper(elementCount + 1); //elementCount=0,只需确保有一个空间可用
* elementData[elementCount++] = e;
* return true;
* {@link java.util.Vector#ensureCapacity(int)}
* 这里传入的参数minCapacity为1,即我们需要的最小容量是1,elementData length是我们初始化时的容量2,此时不会扩容
* if (minCapacity - elementData.length > 0)
* grow(minCapacity);
* elementData[elementCount++] = e; //因为无需扩容,直接根据数组下标赋值就好啦
* 调用链3:
* 此时和调用链2是一样的,不存在扩容
* 调用链4:
* {@link java.util.Vector#add(Object)}
* synchronized修饰,modCount自增,计算容量(如果不够会执行扩容),根据下标为elementData赋值
* 代码:
* modCount++;
* ensureCapacityHelper(elementCount + 1); //elementCount=0,只需确保有一个空间可用
* elementData[elementCount++] = e;
* return true;
* {@link java.util.Vector#ensureCapacity(int)}
* 这里传入的参数minCapacity为3,即我们需要的最小容量是3,elementData length是我们初始化时的容量2,此时会扩容
* if (minCapacity - elementData.length > 0)
* grow(minCapacity);
* {@link java.util.Vector#grow(int)}
* 计算新的容量,因为capacityIncrement初始化时是0,所以newCapacity = oldCapacity + oldCapacity,
* 即新容量等于旧容量的2倍,elementData扩容为原来的2倍数,即4
* 代码:
* 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); //MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
* elementData = Arrays.copyOf(elementData, newCapacity);
* 最后根据下标赋值就好啦
* 代码:
* elementData[elementCount++] = e;
* 调用链5:
* 因为上一步扩容到4,此时不会扩容
* 调用链6:
* 此时因为容量4已用完,会触发扩容,容量扩大到8
*/
private static void createEmptyVector(){
Vector<String> vector = new Vector<>(2); //1
vector.add("aaa"); //2
vector.add("bbb"); //3
vector.add("ccc"); //4
vector.add("ddd"); //5
vector.add("eee"); //6
System.out.println(vector.toString());
}
/**
* 这里初始化时指定每次扩容的大小,交给用户设置
*/
private static void createEmptyVectorWithIncrement(){
Vector<String> vector = new Vector<>(2, 3);//初始容量为2,每次扩容空间为3
vector.add("aaa"); //不扩容,容量为2
vector.add("bbb"); //不扩容,容量为2
vector.add("ccc"); //扩容,扩容为5
vector.add("ddd"); //不扩容,容量为5
vector.add("eee"); //不扩容,容量为5
System.out.println(vector.toString());
}
}
扩容方法:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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 的扩容方式
ArrayList 扩容公式为:newCapacity = oldCapacity + oldCapacity >> 1