跟我一起來讀java源碼(一)

ArrayList

  • 構造函數
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;	
	private static final int DEFAULT_CAPACITY = 10; 
	private static final Object[] EMPTY_ELEMENTDATA = {};
	transient Object[] elementData;
    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);
        }
    }
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {        
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

我們先來看構造函數,ArrayList.java裏面有幾個變量,
final MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;設置最大數組大小,其中 Integer.MAX_VALUE爲 java 中 int最大值 爲的 2 的 31 次方 - 1 = 2147483648 - 1 = 2147483647,所以這裏的值爲 2147489647 - 8=214748363 9;

final DEFAULT_CAPACITY = 10默認大小爲10

final Object[] EMPTY_ELEMENTDATA = {}設置一個空的object對象數組

transient Object[] elementData聲明一個新的 Object 不被序列化的數組,這個數組是主要數組,所有的元素都將放在這個數組裏面

當我們調用無參的構造函數時,初始化當前elementDataEMPTY_ELEMENTDATA,即爲空。

當我們調用有初始化大小的構造函數時,判斷initialCapacity是否大於零,大於則初始化一個大小爲
initialCapacity的Object對象數組。等於零則初始化當前elementDataEMPTY_ELEMENTDATA,即爲空
當小於零,拋出錯誤

當我們調用參數爲集合的構造函數時,此構造函數的意思是將集合轉爲ArrayList,
先將 參數轉爲數組並賦給elementData,判斷當elementData長度不爲零時,判斷是否成功將參數集合轉化爲Object類型的數組,如果轉化成Object類型的數組成功,則將數組進行復制,轉化爲Object類型的數組。
elementData長度爲零時,則初始化當前elementDataEMPTY_ELEMENTDATA,即爲空。

  • 擴容
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  //擴容
       ...
  
    }

	private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
	private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//判斷是否爲空,爲空則返回初始值和設置值中最大的部分
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;//否則返回設置值
    }
	private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//記錄修改次數

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)//判斷大小是否大於當前list對象的長度
            grow(minCapacity);//長度增加
    }
	 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//未增加前長度
        int newCapacity = oldCapacity + (oldCapacity >> 1);//位運算,讓長度增加原來的1.5倍
        if (newCapacity - minCapacity < 0)//當擴容後的長度小於增加後的長度,
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//當擴容後的長度大於最大大小時
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//複製擴容並令當前對象等於它
    }
	private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow溢出
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
        //當長度大於最大長度,則返回int類最大值,否則返回最大長度
        //源碼上有寫最大長度=int類最大值-8
    }

擴容函數爲add()函數調用,函數主體是ensureCapacityInternal,參數爲未擴容前大小+1,
調用 ensureCapacityInternal(int minCapacity)函數後,
再調用 calculateCapacity(Object[] elementData, int minCapacity),這個函數有兩個參數,一個是當前elementData,一個是擴容後的大小 ,這個函數的作用是,判斷elementData是否爲空,如果是,則返回默認大小和擴容後大小的最大值,如果不爲空,則直接返回擴容後的大小
然後調用ensureExplicitCapacity()這個函數的參數是 校驗後的 minCapacity,這個函數的作用是,開始先將修改步驟++,即 modCount++ ,然後執行grow() 進行擴容,
minCapacity表示集合爲了確保添加元素成功的最小容量。在擴容的時候,首先將原元素數組的長度增大1.5倍(oldCapacity + (oldCapacity >> 1)),然後對擴容後的容量與minCapacity進行比較:① 新容量小於minCapacity,則將新容量設爲minCapacity;②新容量大於minCapacity,則指定新容量。最後將舊數組拷貝到擴容後的新數組中。
在這裏插入圖片描述在這裏插入圖片描述
資料:
copyOf詳解
modCount
transient

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