jdk1.5
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = (E[])new Object[initialCapacity]; }
可以看出,如果在初始化ArrayList时进行赋值,那么开始是不会进行扩容的。
如果是一个未赋值初始值的ArrayList,不断对其进行add,那么可以看出再超过oldCapacity的时候,会生成新的newCapacity,值是(oldCapacity*3)/2+1。
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = (E[])new Object[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); } }
可以非常明显的看出,在新增到11个元素的时候,ArrayList内部的elementData数组变成了16个长度的数组。
17时变成25
26时变成38
39时变成58
。。。。
如果开始赋值为2,那么分别也会扩容2,4,7,11.。。。。。
====================================
JDK1.7在新增时扩容:
private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } /** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * 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); }
>>位运算,右移动一位。 整体相当于newCapacity =oldCapacity + 0.5 * oldCapacity
jdk1.7采用位运算比以前的计算方式更快。