1、List和ArrayList的关系
ArrayList实现了List接口。
2、ArrayList的继承实现关系
ArrayList继承自AbstractList实现了List、RandomAccess、Cloneable、Serializable接口
3、关系图
实线表示继承关系、虚线表示实现
4、ArrayList属性
a、DEFAULT_CAPACITY是ArrayList默认的初始容量。
b、EMPTY_ELEMENTDATA是公共的空数组用来给elementData置空的,
c、DEFAULTCAPACITY_EMPTY_ELEMENTDATA也是公共的空数组和EMPTY_ELEMENTDATA不同的是,主要用来在调用不含参数的ArrayList构造函数创建ArrayList对象时初始化elementData.
d、elementData主要用来存放ArrayList对象添加的数据
e、size用来记录ArrayList存放的数据量
5、new ArrayList()的时候的流程
将一个空的数组赋值给了elementData对象
6、调用add方法时的流程
调用add方法时候分了两部分、第一部分是确保空间足够、第二部分是赋值给elementData对象
ensureCapacityInternal方法源代码如下
private void ensureCapacityInternal(int minCapacity) {
// 判断elementData是否为刚刚初始化,如果是,就获取默认的容量和参数容量的两个值中的最大值
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 实际判断和增加容量的方法
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //计数器加1
// 如果需要的容量大于现有数组容量,则增加数组长度
if (minCapacity - elementData.length > 0)
grow(minCapacity); // 增加数组长度
}
private void grow(int minCapacity) {
// 获取现有数组长度
int oldCapacity = elementData.length;
// 增加现有数组长度一半的容量组成新的数组长度
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果是新的数组长度小于需要的数组长度,则新的数组长度赋值为需要的数组长度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果新的数组长度
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 将数组中的内容拷贝到新的数组中并赋值给elementData数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
当添加数据时如果size大于Integer.MAX_VALUE这个长度时会抛出OutOfMemoryError,当size大于 Integer.MAX_VALUE-8这个长度时新的数组长度为Integer.MAX_VALUE,否则新的数组长度为Integer.MAX_VALUE-8