ArrayList数组容量的变化(JDK1.8)
1)一个ArrayList的本质是一个数组,主要由一个对象数组elementData、数据长度size组成以及几个常量值DEFAULT_CAPACITY=10、MAX_ARRAY_SIZE = 2147483639。
2)当创建一个list时,如果没有设置初始容量:
ArrayList list=new ArrayList(),此时list的数组容量为0,size为0.
3)当list添加第一个元素时:
list.add(“1”),
源码:public boolean add(E arg0) {
this.ensureCapacityInternal(this.size + 1);
this.elementData[this.size++] = arg0;
return true;
}
此时会确保容量的大小是否满足。
private void ensureCapacityInternal(int arg0) {
if (this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
arg0 = Math.max(10, arg0);
}
this.ensureExplicitCapacity(arg0);
}
因为创建list时没有初始化数组容量,并且根据ArrayList的构造方法:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
此时的elementData =DEFAULTCAPACITY_EMPTY_ELEMENTDATA,并且size=0;
传入ensureCapacityInternal(int arg0)此方法的arg0为1,经过Math.max(10, arg0)方法
后arg0=10。
private void ensureExplicitCapacity(int arg0) {
++this.modCount;
if (arg0 - this.elementData.length > 0) {
this.grow(arg0);
}
}
private void grow(int arg0) {
int arg1 = this.elementData.length;
int arg2 = arg1 + (arg1 >> 1);
if (arg2 - arg0 < 0) {
arg2 = arg0;
}
if (arg2 - 2147483639 > 0) {
arg2 = hugeCapacity(arg0);
}
this.elementData = Arrays.copyOf(this.elementData, arg2);
}
再通过ensureExplicitCapacity(int arg0) ,grow(int arg0),数组elementData 扩容为10。
size通过this.elementData[this.size++] = arg0变为1。
4)当list中已有10个对象,再增加第一个对象时,通过方法 grow(11),此时arg1=10,
通过int arg2 = arg1 + (arg1 >> 1);可以看到每次扩容的长度为list数组容量的右移一位,此时arg2=10+(10>>1)=15,一次类推。当15满时arg2=15+(15>>1)=22
此时得出结论:
1)ArrayList通过new ArrayList()生成时默认的数组容量为10。
2)当ArrayList中对象数量超出数组容量arg时,数组容量会增加arg>>1。此时的数组容量为arg+(arg>>1)。