直接说结论ArrayList在扩增时扩增1.5倍,Vector扩增2倍大小
ArrayList
是一个不安全的基于数组实现的。
当我们new ArrayList()
的时候,无参数构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//elementData 存储ArrayList元素的数组缓冲区。
也就是说在不指定初始化大小的情况下,一开始是没有大小的,是在第一次添加元素时进行扩充
add方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); //确认是否要扩充内部空间
elementData[size++] = e;//添加元素
return true;
}
//sie 当前集合的大小
ensureCapacityInternal方法
private void ensureCapacityInternal(int minCapacity) {
//若是第一次添加进行初始化。DEFAULT_CAPACITY定义为10,也即是初始化大小为10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);//扩增到指定容积大小
}
ensureExplicitCapacity方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//记录ArrayList操作次数
//真正的检查是否需要扩充的地方
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
grow方法
private void grow(int minCapacity) {
// 获得当前的大小
int oldCapacity = elementData.length;
//设置新的容积大小为当前容积的1.5被 (oldCapacity >> 1)右移缩小
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//要是1.5倍还不够就扩到最大
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 扩充的实际操作
elementData = Arrays.copyOf(elementData, newCapacity);
}
//因为我们一般的数组都是指定好大小之后就不能改了。copyOf()的实际操作就是创一个指定大小(一般比原数组大)的数组,再把原本数组复制进去,在返回新数组。
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
Vector
安全的,基于数组的,不怎么常用的。
Vector和ArrayList前面都差不多,主要区别就在grow方法
private void grow(int minCapacity) {
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);
}
//新的容积大小中判断capacityIncrement是否有值(无参构造时是0),没有就直接增加一倍(为啥是增加0.5倍呢?也不是很复杂啊,这样岂不更好)
//capacityIncrement就是固定增长值,在new时是可以设定
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
//也就是说vector可以设定每次增长的大小。