JDK1.8 ArrarList底层扩容机制
ArrayList list=new ArrayList();
list.add(1);
这里会调用ArrayList的空参构造方法
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
这里的DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的数组
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
elementData就是ArrayList底层用来存元素的数据
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
也就是说在new完ArrayList对象之后就会默认给elementData赋值一个空的元素数组
到这里new 就结束了,接下来看add
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
这里的ensureCapacityInternal就是Arraylist底层的扩容方法
因为是第一次add,在之前这个ArrayList里还没有元素,所以size=0,(size是ArrayList中元素的数量)
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
这个方法用来计算容量,里面进行了判断
如果数组为空,就返回10
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
点进去
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
所以这里传入的minCapacity就是10,再点进这个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是怎样进行扩容的。因为是第一次add,里面默认是没有元素的,所以oldCapacity =0,所以newCapacity也=0,所以执行了第一个if,newCapacity就=10,之后再把扩容后的元素数组和容量赋值给elementData就结束了
结论:
JDK1.8的ArrayList在第一次执行add的时候,底层会给ArrayList的容量设置为10,之后如果要存储的元素超出了10个,就会执行grow扩容,将容量扩充为原来的1.5倍。比起hashmap,这还是很好理解的