跟我一塊兒讀源碼之ArrayList

ArrayList

帶着問題去尋找答案:java

public static void main(String[] args) {
        // 你們都知道ArrayList底層是數組,那ArrayList初始化的數組長度是多少? 
        // 何時初始化的?
        // 咱們都知道數組長度是固定的,ArrayList底層數組是何時擴容的?
    	// 擴容的規律又是什麼樣的呢?
        ArrayList<String> list = new ArrayList<String>();

        list.add("String");
        list.add("integer");
        list.add("integer");

        // ArrayList調用清空方法,數組長度會變化嗎?
        list.clear();

        list.add("1");
    }

全局變量

默認容量數組

/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

空的對象數組函數

/**
 * Shared empty array instance used for empty instances.
 */
 private static final Object[] EMPTY_ELEMENTDATA = {};

默認的空數組this

/**
*  無參構造函數建立的數組
   new ArrayList()
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

存儲數據的數組,不能被序列化spa

transient Object[] elementData; // non-private to simplify nested class access

元素數量.net

/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;

構造方法

無參構造code

public ArrayList() {
    // 建立一個空的數組對象
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

有參構造對象

/**
*  
* @param initialCapacity 初始化容量,不能小於0
*/
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        // 若是初始化容量大於0,建立一個該大小的數組
    	this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        // 若是初始化容量等於0,建立一個空的數組對象
    	this.elementData = EMPTY_ELEMENTDATA;
    } else {
    	throw new IllegalArgumentException("Illegal Capacity: "+
    	initialCapacity);
    }
}
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;
    }
}

方法

一、add()

public boolean add(E e) {
    // 確保初始化容量足夠,進行擴容
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    // 判斷當前數組是否爲默認的空數組對象
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    	// 是,判斷默認容量是否大於minCapacity,大於取默認容量(10)
   		minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    // 擴容
    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    // 記錄修改次數
	modCount++;

    // 若是minCapacity 是否大於當前數組的長度
    if (minCapacity - elementData.length > 0){
        // 擴容
    	grow(minCapacity);
    }
}

// ArrayList動態擴容的核心方法
private void grow(int minCapacity) {
    // 獲取當前數組的容量
    int oldCapacity = elementData.length;
    // 擴容至原來的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // 判斷下新數組容量夠不夠,不夠的話,把min Capacity賦值給newCapacity
    if (newCapacity - minCapacity < 0){
        newCapacity = minCapacity;
    }
    // 判斷新數組容量是否大於數組最大容量
    if (newCapacity - MAX_ARRAY_SIZE > 0){
        newCapacity = hugeCapacity(minCapacity);
    }
    // copy一個新的數組
    elementData = Arrays.copyOf(elementData, newCapacity);
}

// huge:巨大的
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

參考:https://blog.csdn.net/ljcITworld/article/details/52041836 blog

相關文章
相關標籤/搜索