Java集合之ArrayList扩容
JDK1.8
一,ArrayList的构造函数有三种
1.public ArrayList(int initialCapacity) {...},
如果传入的参数initialCapacity合法的话,ArrayList会在elementData属性中存入一个Object数组,长度为传参initialCapacity,这个elementData是什么呢:
翻译为:
存储ArrayList元素的数组缓冲区。ArrayList的容量是这个数组缓冲区的长度。任何空的ArrayList的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
当添加第一个元素时,长度将扩展为DEFAULT_CAPACITY
ArrayList底层实现是数组,所以elementData就是用来存放你的数组数据的,大家都知道ArrayList是个泛型类,数据元素类型检查已经在编译期完成,所以新建的elementData是一个Object数组,这个数组缓存区可以存放任意类型的元素。
2.public ArrayList() {...}
其中DEFAULTCAPACITY_EMPTY_ELEMENTDATA:
翻译为:
用于默认大小的空实例的共享空数组实例。我们将其与EMPTY_ELEMENTDATA区分开来,以便知道何时膨胀多少添加第一个元素。
结合上文的elementData,就知道当新建空的ArrayList时,数组缓冲区elementData存放的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,也就是{},当添加第一个元素add()时,长度将会扩展为DEFAULT_CAPACITY,也就是ArrayList的初始容量10,即Object[10]。
3.public ArrayList(Collection<? extends E> c) {...}
这种情况是传参为集合的情况,ArrayList会将传参的集合转为数组toArray,并赋给elementData,其中toArray返回的就是一个Object数组
二,ArrayList的扩容
看对ArrayList增加元素的时候,用的方法:add
在ensureExplicitCapacity中,当minCapacity大于elementData的长度的时候(比如初始长度10),就需要扩容。看代码minCapacity为calculateCapacity(elementData, minCapacity)返回的值,看代码calculateCapacity方法返回的是传入的值size+1,或者当elementData为新建的{},将对其进行第一次扩容,即10。
扩容的方法:grow()
可以看到,一次扩容为oldCapacity + (oldCapacity >> 1),然后elementData = Arrays.copyOf(elementData, newCapacity);,会新建一个数组,然后将原来的elementData拷贝进去。
最后elementData[size++] = e;将新添加的元素放入数组缓冲区elementData