ArrayList是基于数组实现的,是一个动态的数组,其容量可以自动的增长,我们具体来看一下Arraylist的扩容机制的主要源码。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;//每次增加一个元素,会自增一
return true;
}
public void ensureCapacity(int minCapacity) {
if (minCapacity > 0)
ensureCapacityInternal(minCapacity);
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;//这是继承抽象list父类,用于记录结构修改的次数
// overflow-conscious code
//如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
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);
}
在每次add一个新元素时候,会进行一个容量的判断, ensureCapacityInternal(size + 1); 如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容,进入到扩容的主要方法,grow(minCapacity)。
通过以上代码,我们可知java自动增加ArrayList大小的思路是:向ArrayList添加对象时,原对象数目加1如果大于原底层数组长度,则以适当长度新建一个原数组的拷贝,并修改原数组,指向这个新建数组。原数组自动抛弃(java垃圾回收机制会自动回收)。size则在向数组添加对象,自增1。
举个例子在阐述一下该实现机制的过程,我们初始化一个list,默认的容量为10,我们在增加第11个元素的时候,执行ensureCapacityInternal(size + 1),也就是传入11,进入ensureCapacityInternal方法,此时minCapacity的值为11,数组的长度为10,此时minCapacity-elementData.length > 0,需要执行扩容的方法,具体扩容的方式为扩充为10的1.5倍即可。