JAVA集合-03ArrayList原始碼解析和使用例項
阿新 • • 發佈:2018-12-13
上一章講解了Collection介面下得抽象類和繼承介面,後續深入到具體的實現類,部落格及對應得程式碼可在github上檢視
ArrayList簡介
ArrayList底層實現是陣列,相較於陣列固定大小,ArrayList可以動態的增加;ArrayList繼承AbstractCollection,
實現了List、RandomAccess、Cloneable、Serializable;
- ArrayList繼承AbstractCollection,實現了List介面,使得它有集合的基本操作
- 實現RandomAccess標記了ArrayList可以隨機訪問元素
- 實現Cloneable標記支援克隆
- 實現Serializable標記支援序列化
ArrayList不是執行緒安全的,如果在多執行緒條件下使用CopyOnWriteArrayList或者使用Collections.synchronizedList(List list)轉化為執行緒安全的List
建構函式
- public ArrayList()
- public ArrayList(int initialCapacity)
- public ArrayList(Collection<? extends E> c)
ArrayList提供三種建構函式,第一種構建一個初始化容量為0的ArrayList(查閱資料發現說1.6時候會初始化容量為10),
不過在第一次新增元素時候會讓容量變為10;第二種指定初始化容量大小;第三種初始化容量為Collection大小
結構分析
ArrayList包含兩個重要屬性:size和elementData
- size表示當前ArrayList包含的元素個數,對於方法ArrayList#size返回的就是它
- elementData就是元素存放的位置了
ArrayList原始碼分析(java version:1.8.0_111)
public boolean add(E e) { ensureCapacityInternal(size + 1);//新增元素時候確定容量是否夠用 elementData[size++] = e; return true; }
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//此處就是當容量為0時候新增元素,容量置為10
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)//當容量不夠時候,擴容
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//n+n/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//讓陣列大小變為新的容量大小,這個操作耗時
}
通過閱讀上面的原始碼可以看出ArrayList每次新增元素時候都會檢查容量是否夠,如果不夠的話,需要擴容;
例如size=10,elementData.length=10,此時底層陣列元素填充滿了 當再次新增元素時候ensureCapacityInternal(size + 1)方法
為ensureCapacityInternal(11)->ensureExplicitCapacity(11)->grow(11)返回16,這也是為什麼說每次擴容都是(size+1)的1.5倍