Java集合之ArrayList扩容

JDK1.8

一,ArrayList的构造函数有三种

1.public ArrayList(int initialCapacity) {...},

Java集合之ArrayList扩容

 

如果传入的参数initialCapacity合法的话,ArrayList会在elementData属性中存入一个Object数组,长度为传参initialCapacity,这个elementData是什么呢:

Java集合之ArrayList扩容

 

翻译为:

存储ArrayList元素的数组缓冲区。ArrayList的容量是这个数组缓冲区的长度。任何空的ArrayList的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

当添加第一个元素时,长度将扩展为DEFAULT_CAPACITY

ArrayList底层实现是数组,所以elementData就是用来存放你的数组数据的,大家都知道ArrayList是个泛型类,数据元素类型检查已经在编译期完成,所以新建的elementData是一个Object数组,这个数组缓存区可以存放任意类型的元素。

2.public ArrayList() {...}

Java集合之ArrayList扩容

 

其中DEFAULTCAPACITY_EMPTY_ELEMENTDATA:

Java集合之ArrayList扩容

 

翻译为:

用于默认大小的空实例的共享空数组实例。我们将其与EMPTY_ELEMENTDATA区分开来,以便知道何时膨胀多少添加第一个元素。

结合上文的elementData,就知道当新建空的ArrayList时,数组缓冲区elementData存放的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,也就是{},当添加第一个元素add()时,长度将会扩展为DEFAULT_CAPACITY,也就是ArrayList的初始容量10,即Object[10]。

3.public ArrayList(Collection<? extends E> c) {...}

Java集合之ArrayList扩容

 

这种情况是传参为集合的情况,ArrayList会将传参的集合转为数组toArray,并赋给elementData,其中toArray返回的就是一个Object数组

 

二,ArrayList的扩容

看对ArrayList增加元素的时候,用的方法:add

Java集合之ArrayList扩容

Java集合之ArrayList扩容

Java集合之ArrayList扩容

在ensureExplicitCapacity中,当minCapacity大于elementData的长度的时候(比如初始长度10),就需要扩容。看代码minCapacity为calculateCapacity(elementData, minCapacity)返回的值,看代码calculateCapacity方法返回的是传入的值size+1,或者当elementData为新建的{},将对其进行第一次扩容,即10。

Java集合之ArrayList扩容

扩容的方法:grow()

Java集合之ArrayList扩容可以看到,一次扩容为oldCapacity + (oldCapacity >> 1),然后elementData = Arrays.copyOf(elementData, newCapacity);,会新建一个数组,然后将原来的elementData拷贝进去。

最后elementData[size++] = e;将新添加的元素放入数组缓冲区elementData