remove的核心處理 & add在擴容或其餘進行數組移動操做( eg. addAll、add(index, obj)), 時都涉及數組元素的複製移動:System.arraycopy調用native方式。java
從 index+1 至 end 的元素前移數組
在初始化時若沒指定容量則構建的是空數組,在第一次add時,擴容至DEFAULT_CAPACITY= 10. this
默認下的擴容策略是: 原容量/2 (newCapacity = oldCapacity + (oldCapacity >> 1))spa
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); }
在擴容時,須要經過Arrays.copyOf來複制數組元素(實現也是System.arraycopy)3d
public static void main(String[] args) throws Exception { ArrayList<String> list = new ArrayList<String>(1); Field file = ArrayList.class.getDeclaredField("elementData"); file.setAccessible(true); Object[] object = (Object[]) file.get(list); System.out.println("初始size: " + list.size()); System.out.println("初始數組容量:" + object.length); list.add("1"); Object[] object1 = (Object[]) file.get(list); System.out.println("添加第1個元素後的size:" + list.size()); System.out.println("添加第1個元素後的數組容量:" + object1.length); }
初始化指定容量執行結果:
code
初始化不指定容量執行結果:
blog
Iterator.remove()
方法)對集合增刪元素外,是不容許直接對集合進行增刪操做。不然將會拋出 ConcurrentModificationException
異常。因此,因爲集合的for-Each循環本質上使用的仍是Iterator來迭代,所以也要注意這個陷阱。在for循環中直接remove時拋出異常
排序
普通的for循環方式刪除元素時是經過System.arraycopy調用native的方式進行數組邊界內的複製, size一直會在變化,結果沒法控制(沒法清空數據或下標越界異常)。繼承
而for-Each循環是經過擴展Iterable接口的iterator()方法返回在ArrayList內部對於Iterator接口的實現類Itr來進行處理。接口
類中一個重要元素expectedModCount,初始值等於modCount。
在next()執行階段會調用checkForComodification() 來斷定modCount與expectedModCount是否一致, 不然拋出異常。
而在Iterator.remove方法會從新設置expectedModCount值, 因此當調用Iterator.next等方法時checkForComodification不會報錯。