天天看點

解讀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那個計算)小于傳入要求容量參數,則新容量以傳入的比較大的容量參數為準。

              當傳入容量參數太大,大到超過了數組的容量限定值

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

卻又小于整數限定值

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

-1,那麼新的數組容量以整數限定值

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

-1為準,但是當傳入的容量參數不大于數組的容量限定值時,以容量限定值

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

為準。

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

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

//把舊數組放進新的擴容後的數組

elementData = Arrays.copyOf(elementData, newCapacity);

 Integer.MAX_VALUE:整型的最大值

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

-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;
    }