ArrayList 是 Java 中常用的一个动态数组类,它实现了 List 接口,并且可以随意增删元素。理解 ArrayList 的源码,有助于更深入地了解 Java 的集合框架及其底层实现原理。
ArrayList 的基本结构
ArrayList 内部采用数组来存储元素,并维护一个指向数组的引用。其最重要的成员变量包括:
transient Object[] elementData;
:一个 Object 类型的数组,用于存储 ArrayList 中的元素。private int size;
:一个整型变量,用于表示 ArrayList 中实际元素的个数。private static final int DEFAULT_CAPACITY = 10;
:默认容量,用于初始化时的数组大小。
构造函数
public ArrayList() {
this.elementData = new Object[DEFAULT_CAPACITY];
}
上述代码中,ArrayList 的默认构造函数会创建一个容量为 10 的初始数组。如果用户需要传入初始容量,可以使用如下构造函数:
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);
}
}
添加元素
ArrayList 的add
方法是用于添加元素的主要接口,源码如下:
public boolean add(E e) {
ensureCapacity(size + 1); // 确保容量足够
elementData[size++] = e; // 将新元素添加到数组中,并更新 size
return true;
}
在添加新元素时,首先会调用 ensureCapacity
方法来确保数组的容量,如果当前容量不足,会进行数组扩容。扩容操作通过创建一个更大的数组,并将原数组的元素复制过去来实现。
private void ensureCapacity(int minCapacity) {
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 增长 50%
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
删除元素
ArrayList 中的remove
方法也较为简单:
public E remove(int index) {
rangeCheck(index);
E oldValue = elementData[index];
int numMoved = size - index - 1; // 计算需要移动的元素数量
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null; // 解除引用
return oldValue;
}
在删除操作中,首先检查索引的合法性,然后使用 System.arraycopy
方法来向前移动数组中较后的元素,以填补被删除的元素位置,并将 size 减 1。
总结
ArrayList 是一个功能强大且使用广泛的集合类,它的实现大致分为数组的管理与元素的增删查。通过动态扩容,ArrayList 能够灵活地处理规模不确定的数据集合,方便了程序员处理数据。了解其底层实现有助于我们在性能优化和内存管理上做出更好的决策。
希望以上对 ArrayList 源码的解析能够帮助您更好地理解 Java 集合框架的内部机制。