java ArrayList底层是用Object数组实现的,需要注意的几个参数
DEFAULT_CAPACITY = 10 ; Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
当在使用ArrayList时,若是List<String> list=new ArrayList(); 没有设置initialCapacity,那么在调用list.add时,就会触发一次扩容操作;
扩容操作涉及到的代码如下:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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);
}
list.add时,minCapacity = 1 (size+1);通过calculateCapacity 方法的处理,minCapacity = DEFAULT_CAPACITY = 10;grow方法里面一通+,判断,最后newCapacity为10;
总结:当list初始化时没有设置capacity,则在调用add时,会触发扩容,newCapacity为DEFAULT_CAPACITY = 10 ;触发扩容时,会发生一次数组拷贝, Arrays.copyOf ;最终调用的是System.arraycopy native方法。
当list.size=10时,再次调用list.add(size+1,则minCapacity=11),则会再次触发扩容, int newCapacity = oldCapacity + (oldCapacity >> 1); 这行代码就有效了,扩容后的newCapacity=15; (oldCapacity >> 1)表示右移一位,换成10进制就是 oldCapacity / 2
总结:当list有initialCapacity时,每次扩容 newCapacity = 1.5 * initialCapacity