1.ArrayList结构如何

ArrayList是最常用于存储元素的 Java 类。那么如何ArrayList工作以及为什么每个人都如此喜欢它?

结构ArrayList简单巧妙。每个ArrayList对象包含两个字段:

  • 元素数组
  • 一个size变量,它存储列表中元素的数量

在内部,一个ArrayList对象包含一个最普通的数组!但这还不是全部。还有一个大小变量,它存储列表的长度。它是这样工作的:

最初,列表中数组的长度为 10。变量size为 0。

如果向列表中添加一个元素,它将存储在数组的第 0 个单元格中,并将size增加到 1。

如果再添加一个元素,它将存储在第一个单元格中,并size再次增加 1 并等于 2。

如果在数组中没有更多空间时添加另一个元素,则方法中会发生以下情况add()

  1. 创建一个新数组,其长度是前一个数组长度的一倍半
  2. 旧数组的所有元素都被复制到新数组中。
  3. ArrayList对象中,对新数组的引用替换了对旧数组的引用
  4. 传递的元素保存在新数组的第 10 个单元格中。
  5. 大小变量增加 1 ,现在等于 11

在列表中间添加(插入)元素时会发生类似的情况。现有元素向右移动 1,并将传递的元素写入数组新释放的单元格。

现在我们将考虑涉及列表的最基本场景:


2. 添加一个元素到一个ArrayList

让我们看一下在向列表中添加元素时列表内部会发生什么。在创建 ArrayList 对象后,我们立即在内存中有这样的东西:

向 ArrayList 添加元素

我们有一个ArrayList包含两个字段(两个变量)的对象:一个容器(数组data)和存储元素的数量 ( size)。该data变量存储对可存储 10 个元素的容器(数组)的引用。

如果我们决定将数字 5 添加到数组中,我们会得到下图:

将元素添加到 ArrayList 2

该数组现在存储元素 5 和size == 1

如果现在有人size()在我们的对象上调用该方法ArrayList,返回值将是列表中存储的元素数: 1. 列表中的元素数与数组的存储容量不同。

当前存储容量和数组本身都无法在对象外部访问(可见)ArrayList。这是并将永远是ArrayList的内部数据。

让我们再向列表中添加 7 个数字:10、20、30、40、50、60、70。

现在内存看起来像这样:

向 ArrayList 添加元素

如果您size()现在调用该方法,它将返回数字 8,这是列表中元素的新数量。该值与内部数组的大小无关。

重要的:

这幅图有一个过于简单化的地方。

该类ArrayList不能存储原始类型,因此它使用Integer类型而不是int. 容器不直接存储值 {5, 10, 20, 30, 40, 50, 60, 70},而是对Integer对象的引用。容器存储中的所有空单元格null



3.增加列表的长度

让我们看一下当列表的内部数组中不再有空单元格时,列表内部会发生什么。

假设我们有一个包含 10 个元素的列表:

增加列表的长度

我们决定给它加上数字100 。这是方法中发生的事情add()

第 1 步 — 创建一个新阵列:

增加列表的长度 2

第 2 步 — 将旧数组中的所有元素复制到新数组中:

增加列表的长度 2

第 3 步 — 替换旧数组(更改对对象内部数组的引用ArrayList):

增加列表的长度 3

第 4 步 — 添加新号码,这是我们努力完成的工作:

增加列表的长度 4