關於ArrayList的分析,會從且僅從其添加(add)與刪除(remove)方法入手。html
ArrayList類定義:java
public class ArrayList<E> extends AbstractList<E> implements List<E>
ArrayList基本屬性:數組
/** * Default initial capacity.(默認初始化大小) */ private static final int DEFAULT_CAPACITY = 10; /** * Shared empty array instance used for empty instances. * 空數組,當調用無參數構造函數的時候默認給個空數組 */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 真正存儲數據的數組 */ private transient Object[] elementData; /** * The size of the ArrayList (the number of elements it contains). * 所存儲數據的數量 */
ArrayList的add方法:框架
/** * Appends the specified element to the end of this list. * 插入數據,每一次都是從末尾插入 */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { //此處表示若爲空數組 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++;//jdk源碼閱讀筆記之java集合框架(三)(modCount) if (minCapacity - elementData.length > 0) /** * minCapacity=size+1 * 只用當數組實際存儲元素數量+1大於數組長度是,需擴容 */ grow(minCapacity); } /** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * 提升數組容量以確保至少可以存儲minimum數量的數據 */ private void grow(int minCapacity) { int oldCapacity = elementData.length; //帶符號右移等價於除以2,因此每一次擴容以後,數組的長度爲原來的1.5倍。 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //因爲擴容以後產生了新數組,此處是新老數組之間數據的轉移 elementData = Arrays.copyOf(elementData, newCapacity); }
ArrayList的remove方法:ide
remove方法分爲 remove(Object o) 與 remove(int index)。倆方法相似,因此任挑其一進行分析。函數
/** * 移除指定下標的元素 */ public E remove(int index) { rangeCheck(index);//下標越界檢查 modCount++; //"http://www.cnblogs.com/jw93/p/6845825.html"詳細介紹 E oldValue = elementData(index); /** * 移除某一元素以後,須要將該元素後面的元素向前移動 * numMoved表示須要移動的元素個數 */ int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved);//此處爲native方法 elementData[--size] = null; // clear to let GC do its work return oldValue; } /** * 下標越界檢查 */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index));//拋出數組下標越界 } /** * 拋出異常時詳細信息 */ private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; }