Java ArrayList 内部工作原理

2025年8月12日 | 阅读 4 分钟

什么是 ArrayList?

在 Java 中,ArrayList 是一个可调整大小的数组实现。ArrayList 动态扩展,确保总有空间添加更多元素。Object 类数组作为 ArrayList 的底层数据结构。在 Java 中,ArrayList 类有三个构造函数。它自己有 readObject 和 writeObject 方法。ArrayList 的 Object 数组是临时的。它实现了 RandomAccess、Cloneable 和 java.io。以及支持序列化(Java 中的标记接口)。

ArrayList 中的元素保存在哪里?

ArrayList 是一个 Object 类数组,定义如下:

许多程序员可能想知道为什么它是临时的,为什么不直接序列化 ArrayList。

序列化 ArrayList 没有难度,因为它有自己的 readObject 和 writeObject 过程版本,这就是为什么这个 Object 数组是临时的。

创建 ArrayList 时会发生什么?

要在 Java 中创建 ArrayList,有三个构造函数。

1. public ArrayList(int initialCapacity): 使用此构造函数时,我们可以提供一个初始容量,而不是依赖 ArrayList 类中定义的默认容量。

例如

ArrayList 类中的代码如下:

其中 EMPTY_ELEMENTDATA 定义为:

很明显,如果提供的容量大于零,则 elementData 数组将以该容量创建,但如果提供的容量为零,则 elementData 数组将以一个空的 Object 数组创建。当添加第一个元素时,ArrayList 将扩展。

2. public ArrayList(): ArrayList 类的默认构造函数用于创建 ArrayList,如下所示:

ArrayList 类中默认构造函数的代码如下:

其中 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 定义为:

如上所述,它最初将使用一个空数组初始化,只有在向列表中添加第一个元素时才会增长。

3. public ArrayList(Collection<? extends E> c): 如果我们想创建一个包含指定集合元素的列表,我们可以使用此构造函数。在此构造函数中,会检查传递的集合的长度,如果长度大于零,则使用 Arrays.copyOf 方法将集合复制到 elementData 数组。

ArrayList 如何自动增长?

当我们向 ArrayList 添加一个元素时,它首先检查数组是否有足够的容量来容纳新元素。如果没有,则计算新容量,该容量比前一个容量高 50%,然后将数组按该量扩展(实际上使用 Arrays.copyOf 返回原数组并增加到新长度)。

以下 Java 代码演示了 Java ArrayList 的实现:

其中 DEFAULT_CAPACITY 定义为:

如上所述,决定是否需要扩展数组,如果需要,则调用 grow 函数。

注意,直到 Java 6,新容量的计算如下:

它还将通过右移运算符增加前一个容量的 50%。

让我们通过一个 Java 程序来理解。

Test.java

输出

5  

如果默认容量设置为 10,

它将返回 15

如果从 ArrayList 中删除元素会怎样?

当从 Java 中的 ArrayList 中删除元素时,必须使用 remove (int I(即使用索引)或 remove (Object o) 来填充底层数组中由元素删除产生的间隙。通过将任何后续组件向左移动来实现这一点(将其索引减一)。这是通过 System.arrayCopy 方法完成的。

源位置是 index+1,而目标位置是 index。由于索引处的元素已被删除,因此从 index+1 开始的元素被移动到从 index 开始的目标位置。