您好,登錄后才能下訂單哦!
Java中怎么擴容ArrayList,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
注意:
不同的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的使用性能,因此當我們確定添加元素的個數的時候,我們可以事先知道并指定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); } }
看完上述內容,你們掌握Java中怎么擴容ArrayList的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。