jdk源碼閱讀筆記之java集合框架(二)(ArrayList)

關於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).
     * 所存儲數據的數量
     */
View Code

 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;
    }
相關文章
相關標籤/搜索