1. 程式人生 > 其它 >java ArrayList 原始碼解讀

java ArrayList 原始碼解讀

java ArrayList 原始碼解讀

ArrayList 類有三個構造方法,分別為無參構造方法,傳int構造方法,和傳集合構造方法
    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    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 a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
其中無參構造方法初始化完成之後 建立一個空的Object陣列 名為 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.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
在第一次呼叫add的時候將 elementData 擴容為10;
    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;



private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);//拿到預設值 f返回最大值
        }
        return minCapacity;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private void ensureExplicitCapacity(int minCapacity) { //這裡傳入為 10
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0) //這時候初始化的時候elementData.length為0 minCapacity為10 呼叫 grow方法擴容
            grow(minCapacity);
    }
此時elementData 長度為 10 可以存放 10個物件,當第11個物件被 add的時候,判斷是否需要擴容為true 則進入擴容邏輯,擴容jdk8 邏輯為 將elementData 陣列長度擴容為 原有長度的1.5倍,程式碼中提現為
int newCapacity = oldCapacity + (oldCapacity >> 1);
之後擴容邏輯不變
有參傳int構造方法int值為 初始化 elementData 陣列長度
    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    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);
        }
    }

讀原始碼可以看到,傳入值 大於0 則建立一個 長度為 該值的 Object陣列 並且賦值給elementData,如果傳入值為 0 則建立一個長度為10的Object陣列 並且賦值給elementData.

還有一個構造放法, 啊 我累了 不看了