參考http://www.jianshu.com/p/f174d49b391c
ensureCapacity(),該方法就是 ArrayList 的擴容方法。在前面就提過 ArrayList 每次新增元素時都會需要進行容量檢測判斷,若新增元素后元素的個數會超過 ArrayList 的容量,就會進行擴容操作來滿足新增元素的需求。所以當我們清楚知道業務數據量或者需要插入大量元素前,我可以使用 ensureCapacity 來手動增加 ArrayList 實例的容量,以減少遞增式再分配的數量。
public void ensureCapacity(int minCapacity) { //修改計時器 modCount++; //ArrayList容量大小 int oldCapacity = elementData.length; /* * 若當前需要的長度大於當前數組的長度時,進行擴容操 作 */ if (minCapacity > oldCapacity) { Object oldData[] = elementData; //計算新的容量大小,為當前容量的1.5倍 int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; //數組拷貝,生成新的數組 elementData = Arrays.copyOf(elementData, newCapacity); } }
在這里有一個疑問,為什么每次擴容處理會是 1.5 倍,而不是 2.5、3、4 倍呢?通過 google 查找,發現 1.5 倍的擴容是最好的倍數。因為一次性擴容太大(例如 2.5 倍)可能會浪費更多的內存(1.5 倍最多浪費 33%,而 2.5 被最多會浪費 60%,3.5 倍則會浪費 71%……)。但是一次性擴容太小,需要多次對數組重新分配內存,對性能消耗比較嚴重。所以 1.5 倍剛剛好,既能滿足性能需求,也不會造成很大的內存消耗。
處理這個 ensureCapacity() 這個擴容數組外,ArrayList 還給我們提供了將底層數組的容量調整為當前列表保存的實際元素的大小的功能。它可以通過 trimToSize() 方法來實現。該方法可以最小化 ArrayList 實例的存儲量。
public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } }