只记录目前为止关注的。JDK1.8
一、基础属性
1.1 内部参数
//空存储实例。直接new ArrayList()便是以该空数组作为实例
private static final Object[] EMPTY_ELEMENTDATA = {};
//默认容量大小,在由空实例进行首次扩容时,扩到到该长度。
//实际使用中,并未实际存在Capacity这个参数,需要扩容时直接根据旧数组的length进行扩容
private static final int DEFAULT_CAPACITY = 10;
//实际存储数组
transient Object[] elementData;
//存储元素个数
private int size;
1.2 三个重载构造方法
//构建一个空实例,elementData指向容量为0的空数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//以给定容量初始化存储数组
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//以集合初始化创建列表
//步骤:1. 调用toArray(),将给定集合转成数组(以ArrayList为例,toArray()返回的是实际存在元素的那部分数组,即[0,size))
//2. 让size直接等于给定集合的数组长度
//3. 判断size如果为0则直接创建空存储实例,否则使用Arrays.copyOf将给定集合数组复制一份(浅拷贝),作为存储数组
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
// ArrayList 的 toArray()源码,复制[0,size)部分返回
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
二、操作及策略
2.1 动态扩容
扩容策略:当数组全满了才扩容,新长度=旧长度+旧长度*2
动态扩容有两个入口:供用户调用的显式扩容ensureCapacity()
和添加元素时的隐式扩容ensureCapacityInternal()
,不过均是调用ensureExplicitCapacity()
来根据传入所需容量值决定是否扩容,最终实际扩容操作在grow()
方法中。
//显式扩容入口方法
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
//隐式扩容入口方法
//其中参数 minCapacity 值为 size+1,由add方法调用传入
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//添加方法
public boolean add(E e) {
// 传入最小所需容量为size+1
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//计算所需容量,实则不需要计算
//只是单纯判断当前是否是空实例,为空就话返回 "默认容量"与minCapacity之间的较大值,不为空直接返回minCapacity
//参数 minCapacity 只有两种情况:
// 1. 隐式扩容时,如add()传入,其值为 size+1
// 2. 显式扩容,用户指定
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//在此处,根据最小所需容量来判断是否实际进行扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0) //若已经占满,才进行扩容
grow(minCapacity);
}
//实际扩容方法
//可以看到扩容策略为:length+length*2
//然后调用Arrays.copyOf浅复制
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //旧长度+旧长度*2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}