ArrayList源碼簡單剖析


    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] 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) { // 1.ArrayList構造方法,可以指定默認的初始化大小,當然還有個無參構造,默認是個Object類型空數組
        // 2.下面的邏輯判斷應該都能看的懂,比較簡單
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }


    // get方法:傳遞個索引值過來,判斷索引是否大於size;如果大於拋出個索引越界異常,否則返回數組對應索引的上的元素
     public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }


    //set方法:通過索引獲取到該位置上的元素,賦值給了oldValue這個變量;然後再把傳遞過來的元素賦值到該位置的索引上;通過set改變元素時,可以返回老的元素
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }


    //add方法: 6.跟的方法有點深,不好意思;但總體來說就是add一個元素進去,在當前size+1;如果size長度不夠就去填充;最後把這個元素指定到當前size的數組索引上返回布爾值TRUE
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 1.當add一個元素進來的時候當前的size+1值走ensureCapacityInternal方法
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));// 2.elementData默認是一個空數組
    }

     private static int calculateCapacity(Object[] elementData, int minCapacity) { 
        // 3.判斷是否是空數組
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            // 4.當添加一個元素進來的時候,ArrayList會默認擴容到10
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    // 5.下面這個幾個方法簡單可以理解成,一個擴容的過程就不多說了
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) 
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :   // Integer.MAX_VALUE  一個持有最大值一個 int可以有2的31次方-1。 
            MAX_ARRAY_SIZE;
    }

    // remove方法:
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        //size是這個集合的長度,獲取傳遞過來的索引位置並且-1的個數,然後通過 System.arraycopy方法進行復制,把原數組覆蓋.最後把這個size的最後一位至爲null,並且size--的方式進行刪除
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; 

        return oldValue;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章