结构图

Iterable为ArraysList提供迭代器的功能Collection定义了集合的基础add、get、remote、...等功能AbstractCollection对Collection定义的接口进行了默认实现List定义列表相关接口AbstractList对List定义的接口进行了默认实现RandomAccess为其增加快速随机访问的能力Cloneable为其增加克隆的能力Serializable为其增加序列化
关键属性及常用方法
关键属性
// 默认容量
private static final int DEFAULT_CAPACITY = 10;
// 空的元素数据
private static final Object[] EMPTY_ELEMENTDATA = {};
// 元素数据,存储目标元素
transient Object[] elementData;
// 元素大小 >= elementData.length;
private int size;
常用方法
构造器
ArraysList提供三个构造器,分别为
- 无参构造器
public ArrayList() {
// 初始化原数据
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
- 通过初始容量进行初始化
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
- 通过集合进行初始化
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// 当c.toArray() 返回的不为 Object[]时,将原数据通过Arrays.copyOf()方法转化为Object[]
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
基础方法
- 增加元素:
add()
public boolean add(E e) {
// 原数据扩容
ensureCapacityInternal(size + 1);
// 新元素赋值
elementData[size++] = e;
return true;
}
// 内部扩容
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 扩容
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 新容量>当前数据容量,进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 新容量 = 老容量 * 1.5
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 新容量小于最小容量,则新容量=最小容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 当新容量已经超过最大的数组大小
// 其中 MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 通过最小容量重新获取新容量
newCapacity = hugeCapacity(minCapacity);
// 原数据赋值
elementData = Arrays.copyOf(elementData, newCapacity);
}
// 获取最大容量
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
- 批量添加元素:
// 添加到元素数据的末尾
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
// 检查容量&扩容
ensureCapacityInternal(size + numNew); // Increments modCount
// 原元素赋值
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
// 添加到元素数据的指定位置
public boolean addAll(int index, Collection<? extends E> c) {
// 范围检查
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
// 检查容量&扩容
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
// 将 index -> size -1 的元素拷贝到元素数据的末尾
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 将目标元素拷贝到指定位置
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
- 获取元素:
get()
public E get(int index) {
// 范围检查
rangeCheck(index);
// 返回元素
return elementData(index);
}
- 设置元素到指定位置:
set()
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
- 移除指定元素:
remove()
// 删除指定位置的元素
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
// 当删除的元素不是最后一个时
if (numMoved > 0)
// 将index后的元素向前拷贝
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
// 删除指定元素
// 只会删除满足条件的第一个元素
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
// 快速删除
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
// 快速删除
fastRemove(index);
return true;
}
}
return false;
}
// 快速删除方法,与 remote(int index)方法实现一致
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
- 清空元素:
clear()
public void clear() {
modCount++;
// clear to let GC do its work
// 将元素数据数组的所有item赋值为null
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
- 批量删除元素:
batchRemove()
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
// 将不满足删除条件的元素向前移动
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
// 当抛出了异常时,可能会出现 r != size 的情况
// 此时直接将未匹配的数据直接拷贝到最后一个移动后的数据后面
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
// 当存在删除的数据时,将不满足条件后的索引位赋值为null
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
上面从增删改查四个角度解析了ArrayList的基本源码,可以得出它的内部实现是一个数组。在新增元素时,当添加后的元素大小超过了元素数组的长度时,会触发它的扩容机制,以添加后的元素大小的1.5倍对元素数组进行扩容。