直接說結論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可以設定每次增長的大小。