ArrayList扩容原理,源码分析

List list = new ArrayList();
1. 刚创建的ArrayList对象,第一次调用add方法时。会触发grow()方法(只是new一个ArrayList,不调用add方法的话,ArrayList底层的 数组的长度是 0,当第一次调用add方法后,数组被初始化为长度为10)。
2. 在grow()方法中会初始化一个长度为10的Object数组。数组名为elementData。之后,当多次调用add,elementData数组中都存满对象,再调用一次add方法,则会使ensureExplicitCapacity方法中的 if (minCapacity - elementData.length > 0)判断条件为真,从而触发grow()方法,在该方法中调用Arrays.copyOf()进行数组扩容(实际上是创建一个新数组,长度为原数组的1.5倍,将原数组中的值复制到新数组中)。 扩容为原数组的约1.5倍(int newCapacity = oldCapacity + (oldCapacity >> 1);实现,newCapacity 约等于oldCapacity 的1.5倍。其中>>表示二进制数左移一个单位,相当于原数值除以2,若有余数向下取整)。
3. 下面是ArrayList中的部分源码,调用list.add()方法时,在add方法中调用ensureCapacityInternal方法,在ensureCapacityInternal方法中又调用ensureExplicitCapacity方法,ensureExplicitCapacity方法中根据判断条件if (minCapacity - elementData.length > 0)来判断是否需要扩容,若需要扩容则调用grow方法来实现扩容。
private static final int DEFAULT_CAPACITY = 10;
transient Object[] elementData;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public boolean add(E e) {
ensureCapacityInternal(size + 1);//第一次调用add()方法size =0
elementData[size++] = e;
return true;
}

private void ensureCapacityInternal(int minCapacity) { //第一次调用add()方法minCapacity=1
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //第一次调用add()方法true
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //第一次调用add()方法minCapacity=10
}
ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) { //第一次调用add()方法minCapacity=10
modCount++;
if (minCapacity - elementData.length > 0) //第一次调用add()方法10-0=10>0
grow(minCapacity);
}

private void grow(int minCapacity) { //第一次调用add()方法minCapacity=10
int oldCapacity = elementData.length; //第一次调用add()方法oldCapacity =0
int newCapacity = oldCapacity + (oldCapacity >> 1); //第一次调用add()方法newCapacity =0
if (newCapacity - minCapacity < 0) //第一次调用add()方法0-10=-10<0
newCapacity = minCapacity; //第一次调用add()方法newCapacity=10
if (newCapacity - MAX_ARRAY_SIZE > 0) //第一次调用add()方法false
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值