Java ArrayList的自動擴容機制__java

來源:互聯網
上載者:User

注意:

不同的JDK版本的擴容機制可能有差異
實驗環境:JDK1.8

擴容機制

當向ArrayList中添加元素的時候,ArrayList如果要滿足新元素的儲存超過ArrayList儲存新元素前的儲存能力,ArrayList會增強自身的儲存能力,已達到儲存新元素的要求

ArrayList:本質通過內部維護的數組對象進行資料存放區

①:分析ArrayList的add(E)方法

 public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }

分析:add方法首先通過ensureCapacityInternal()方法確保當前ArrayList維護的數組具有儲存新元素的能力,經過處理之後將元素儲存在數組elementData的尾部
elementData:ArrayList真正用於儲存元素的數組

②:分析ensureCapacityInternal方法

private void ensureCapacityInternal(int minCapacity) {        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);    }

分析:ensureCapacityInternal判斷ArrayList預設的元素儲存資料是否為空白,為空白則設定最小要求的儲存能力為必要儲存的元素和預設儲存元素個數的兩個資料之間的最大值,然後調用ensureExplicitCapacity方法實現這種最低要求的儲存能力

注意:ArrayList的儲存空間並不是需要一個建立一個,而是分階段性的建立,一般會預留儲存空間。
例如,如果ArrayList需要儲存10個元素,恰好ArrayList只能儲存6個元素,剩餘4個元素無法儲存,ArrayList可能會一次性擴充10個元素,這種ArrayList就有20個元素的儲存能力,在儲存能力範圍內,下次再存放元素,就不需要再次擴容

③:分析ensureExplicitCapacity方法:

 private void ensureExplicitCapacity(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }

分析:如果最低要求的儲存能力>ArrayList已有的儲存能力,這就表示ArrayList的儲存能力不足,因此需要調用 grow();方法進行擴容
④:分析grow()方法

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

分析:當ArrayList擴容的時候,首先會設定新的儲存能力為原來的1.5倍

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

如果擴容之後還是不能滿足要求則MAX_ARRAY_SIZE比較,求取最大值,
如果MAX_ARRAY_SIZE大小的能力還是不能滿足則通過hugeCapacity()方法擷取ArrayList能允許的最大值:

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

從hugeCapacity方法看出,ArrayList最大的儲存能力:儲存元素的個數為整型的範圍。
確定ArrayList擴容之後最新的可儲存元素個數時,調用
elementData = Arrays.copyOf(elementData, newCapacity);
實現elementData數組的擴容,整個流程就是ArrayList的自動擴容機制工作流程

擴充:
ArrayList的自動擴容機制底層藉助於System實現

  public static native void arraycopy  (Object src,  int  srcPos,   Object dest, int destPos,   int length);

arraycopy標識為native意味JDK的本地庫,不可避免的會進行IO操作,如果頻繁的對ArrayList進行擴容,毫不疑問會降低ArrayList的使用效能,因此當我們確定添加元素的個數的時候,我們可以事Crowdsourced Security Testing道並指定ArrayList的可儲存元素的個數,這樣當我們向ArrayList中加入元素的時候,就可以避免ArrayList的自動擴容,從而提高ArrayList的效能

ArrayList含參建構函式:初始化時指定儲存元素的能力:

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.