ArrayList源码解析
属性分析:
默认初始容量
private static final int DEFAULT_CAPACITY = 10;
ArrayList空实例共享一个空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
用于默认大小的空实例的共享空数组实例。
将其与EMPTY_ELEMENTDATA区分开来,用来了解当添加第一个元素的时候需要创建多大的空间
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
真正存储ArrayList中元素的数组
transient Object[] elementData;
ArrayList中的元素个数
private int size;
构造方法
无参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
有参构造
普通方法
添加方法
首先,我们来看看这个add方法:
public boolean add(E e) {
//确认list容量,看看是否需要容量增加
ensureCapacityInternal(size + 1); // Increments modCount!!
//将元素放到已有元素的下一个位置
elementData[size++] = e;
return true;
}
接下来我们来看看这个小容量(+1)是否满足我们的需求:
// 获取到满足需求的最小容量
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
先将这个容量值传入calculateCapacity方法,计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// elementData是空列表
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 扩容数组到DEFAULT_CAPACITY(10)
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// return size+1
return minCapacity;
}
然后判断是否需要扩容,如果需要扩容,就调用grow()方法,进行扩容
// 判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
//调用grow方法进行真正地扩容
grow(minCapacity);
}
步骤解析:
1,当添加第1个元素到 ArrayList 中时,minCapacity 为size+1=1,elementData还是空的list,elementData.length=0 ,所有会执行return Math.max(DEFAULT_CAPACITY, minCapacity) 返回值为DEFAULT_CAPACITY,也就是10 ;
minCapacity变为10。此时,minCapacity - elementData.length > 0成立,所以会进入 grow(minCapacity) 方法真正扩容。
2,当添加第2个元素时,minCapacity 为 size+1 =2,由于elementData.length在添加第一个元素后已经扩容成10了。此时,minCapacity - elementData.length > 0 不成立,不会执行grow(minCapacity) 方法,即不会扩容。
3,添加第 3、4、5…到第10个元素时,依然不会扩容,数组容量还是为10。
直到添加第11个元素,minCapacity - elementData.length > 0 成立,执行grow 方法进行扩容。
所以,接下来看看grow()是怎么实现的~
private void grow(int minCapacity) {//11
// oldCapacity为旧容量
int oldCapacity = elementData.length;//10
// 位移运算符比普通运算符的运算快很多。>>表示将oldCapacity右移一位,(oldCapacity >> 1)相当于oldCapacity /2
// 将新容量更新为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 若新容量还是小于最小需求容量
if (newCapacity - minCapacity < 0)
// 直接最小需求容量当作数组的新容量
newCapacity = minCapacity;
//如果minCapacity大于最大容量,则新容量则为`Integer.MAX_VALUE`,否则,新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8`。
// 新容量大于MAX_ARRAY_SIZE,
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 执行hugeCapacity()方法
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
ArrayList创建空实例以及扩容总结:
1,创建无参构造的ArrayList,默认创建的是空数组,长度为0
2,当往这个ArrayList对象中,放入第一个元素之后,数组扩容,扩容到默认长度10
3,当放入到第11个元素的时候,数组继续扩容,扩容到原数组长度的1.5倍,即将10扩容到15