List介面常用實現類對比
阿新 • • 發佈:2021-07-22
相同點
都實現了List介面 儲存了有序 可重複的資料
不同點
ArrayList
執行緒不安全 但是效率高 底層使用 Object[] elementData 實現
LinkedList
底層使用雙向連結串列資料結構 對於頻繁的插入 刪除 該類比ArrayList效率高
Vector
執行緒安全 但是效率低 底層使用 Object[] elementData 實現
原始碼分析
ArrayList
JDK8
中 ArrayList
底層使用Object[] elementData陣列儲存 預設初始化大小
為 10
/** * Default initial capacity. 預設初始化容量 10 */ private static final int DEFAULT_CAPACITY = 10; /** * Shared empty array instance used for empty instances. * 用於空例項的陣列 即 new ArrayList(0) */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. * 用於預設大小的空例項的共享空陣列例項 * 將其與 EMPTY_ELEMENTDATA 區別開來,以便知道何時應該膨脹多少 * 新增第一個元素。 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; transient Object[] elementData; // non-private to simplify nested class access private int size; // 陣列大小
建構函式
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(Collection<? extends E> c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { elementData = a; } else { elementData = Arrays.copyOf(a, size, Object[].class); } } else { // replace with empty array. elementData = EMPTY_ELEMENTDATA; } }
有三種建構函式 無參建構函式 有參建構函式(集合型別的建構函式 int型別的建構函式)
ArrayList list = new ArrayList();
此時呼叫ArrayList無參建構函式 底層Object[] elementData
初始化為{}
沒有建立集合大小!!!!!
add方法
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
當例項ArrayList後 得到list物件 此時Object[] elementData
初始化為{}
呼叫add
方法時
此時容量才被初始化為 10
因為elementData
為 {} 長度為 0 沒有達到最低容量要求 必須得擴容了
小結
- 只要集合長度沒有達到最小容量 必須得擴容 長度一般是原來的1.5倍(位運算子 >>1 相當於 原來的容量 / 2 + 原來的容量)
- ArrayList物件建立類似於 單例模式的懶漢式 延遲了陣列的建立 節省記憶體
LinkedList
LinkedList linkList = new LinkedList();
linkList.add("wwbao");
public boolean add(E e) {
linkLast(e); // 呼叫linkLast方法 並且將新增的值也傳過去
return true;
}
示意圖
小結
- 雙向連結串列中 第一個節點的
prev
永遠為null
最後一個節點的next
永遠為null
- 上一個節點的
next
指向下一個節點 下一個節點的prev
指向上一個節點