解讀ArrayList中的grow(int minCapacity)方法

查看源碼:

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
    }

由源碼註釋可得知,此方法用來保證數組至少可以容納由minimum capacity參數指定的元素數。

大白話就是,容量要保證能裝下mincapacity所指定的容量大小

源碼分析

//把數組的長度賦給oldCapacity

int oldCapacity = elementData.length;

//新的數組容量=老的數組長度的1.5倍。oldCapacity >> 1 相當於除以2

int newCapacity = oldCapacity + (oldCapacity >> 1);

//如果新的數組容量newCapacity小於傳入的參數要求的最小容量minCapacity,那麼新的數組容量以傳入的容量參數爲準。

if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;

//如果新的數組容量newCapacity大於數組能容納的最大元素個數 MAX_ARRAY_SIZE 2^{31}-1-8

//那麼再判斷傳入的參數minCapacity是否大於MAX_ARRAY_SIZE,如果minCapacity大於MAX_ARRAY_SIZE,那麼//newCapacity等於Integer.MAX_VALUE,否者newCapacity等於MAX_ARRAY_SIZE

if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);

這裏有3個判斷:

  • if (newCapacity - minCapacity < 0)
  • if (newCapacity - MAX_ARRAY_SIZE > 0)
  • 以及hugeCapacity(minCapacity);函數中的:
  • (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;

意義爲:當重新計算的容量(x1.5那個計算)小於傳入要求容量參數,則新容量以傳入的比較大的容量參數爲準。

              當傳入容量參數太大,大到超過了數組的容量限定值2^{31}-1-8卻又小於整數限定值 2^{31}-1,那麼新的數組容量以整數限定值 2^{31}-1爲準,但是當傳入的容量參數不大於數組的容量限定值時,以容量限定值2^{31}-1-8爲準。


// minCapacity is usually close to size, so this is a win:

//MinCapacity通常接近size,所以這是一個勝利

//把舊數組放進新的擴容後的數組
elementData = Arrays.copyOf(elementData, newCapacity);

 Integer.MAX_VALUE:整型的最大值 2^{31}-1

    /**
     * A constant holding the maximum value an {@code int} can
     * have, 2<sup>31</sup>-1.
     */
    @Native public static final int   MAX_VALUE = 0x7fffffff;

MAX_ARRAY_SIZE:

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

hugeCapacity:

傳入的參數必須大於0,否者報錯

判斷傳入的參數minCapacity是否大於MAX_ARRAY_SIZE,如果minCapacity大於MAX_ARRAY_SIZE

返回Integer.MAX_VALUE,否者返回MAX_ARRAY_SIZE。

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

 

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