ArrayList與LinkedList簡要分析
實現list介面的集合有序,可重複。set介面則相反無序,不可重複;
ArrayList:
一.底層
底層是動態陣列結構,既擁有陣列的特性;對於查詢資料非常高效,新增資料需要改變陣列後面元素移動位置,效率慢;
二:擴容原始碼解析
介紹的是無參構造方法:
public ArrayList() {
// elementData:底層陣列 ,DEFAULTCAPACITY_EMPTY_ELEMENTDATA:空陣列
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
通過List list = new ArrayList();根據構造方法可看出建立一個空陣列;
對list新增資料: list.add(1);
/** * 原始碼add的實現 * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
1.ensureCapacityInternal(size + 1)方法進行擴容:
private void ensureCapacityInternal(int minCapacity) {
// minCapacity:陣列最小大小
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
剛剛就是通過無參構造方法new的陣列,所以陣列elementData等於空陣列;
2.判斷陣列預設值與陣列最小size(minCapacity)比大小,返回最大值;因為是空陣列所以minCapacity為1,陣列預設值為10
即返回minCapacity=10;
3.是否擴容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
modCount++暫且不說;原陣列為空,所以elementData.length一定是0,即呼叫grow方法進行擴容;
4.擴容之後陣列的新容量,並複製原陣列
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
很清晰的看出擴容為原來的1.5倍(>>1:表示位運算,除以2),若擴容之後新容量還沒有minCapacity大,
那麼新容量大小等於minCapacity,複製原陣列;
最後elementData[size++] = e;對陣列新增元素;
LindedList:
一:底層
底層是連結串列結構,因為新增刪除資料時只需要在相應的節點插入一個數據即可,所以對於新增刪除非常高效;