1. 底層不同
- ArrayList基於動態數組
- LinkedList基於雙向鏈表
2. 查詢、插入、刪除的效率不同
- 對於隨機訪問get,設定值set方法,ArrayList的效率高於LinkedList,因爲動態數組可以隨機訪問的,適用於查詢很多的場景。而LinkedList需要通過移動指針一步一步到節點處,比較費時。
- 對於插入、刪除方法,LinkedList的效率要優於ArrayList,爲啥呢,LinkedList只需要移動指針指向需要的節點對象即可以,而ArrayList需要移動數據來填補被刪除的對象的空間
3. 使用場景不同
-
當經常需要執行查詢操作時,適合使用ArrayListList
-
當我們不知道數據量的大小時或者經常執行插入刪除的操作,適合使用LinkedList
4. ArrayList需要擴容的問題
當ArrayList的空間不夠用時,會自動申請內存,叫做擴容。
/**
* minCapacity:當前需要的容量是minCapacity,擴容後的容量應當大於等於minCapacity
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length; // 擴容前的容量
int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量等於擴容前容量的1.5倍
// 如果新容量還不夠用,那麼就擴容到minCapacity得了
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果新容量超過ArrayList最大容量,那麼就用最大容量了(ArrayList的容量總得有個上限吧)
// 插一句:最大容量爲:0x7fffffff-8
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 擴容的核心就是這句話,將舊數組裏的內容複製到新數組裏
// 這個操作很耗時,因此我們應當儘量減少擴容
elementData = Arrays.copyOf(elementData, newCapacity);
}
在這裏可以很清楚的看到擴容容量的計算:
int newCapacity = oldCapacity + (oldCapacity >> 1)
調用無參構造函數默認初始容量爲10
其中oldCapacity是原來的容量大小,oldCapacity >> 1 爲位運算的右移操作,右移一位相當於除以2,所以這句代碼就等於int newCapacity = oldCapacity + oldCapacity / 2;即容量擴大爲原來的1.5倍(注意我這裏使用的是jdk1.8,沒記錯的話1.7也是一樣的),獲取newCapacity後再對newCapacity的大小進行判斷,如果仍然小於minCapacity,則直接讓newCapacity 等於minCapacity,而不再計算1.5倍的擴容。然後還要再進行一步判斷,即判斷當前新容量是否超過最大的容量 if (newCapacity - MAX_ARRAY_SIZE > 0),如果超過,則調用hugeCapacity方法,傳進去的是minCapacity,即新增元素後需要的最小容量:
轉載:https://blog.csdn.net/u010429424/article/details/76220058