什么是 ArrayList 的扩容?📦
我们都知道 ArrayList 是一个可以动态增长的数组,就像一个可伸缩的背包🎒,随着你往里面不断加东西,它会自动变大,不用担心背包会装不下。
ArrayList 的扩容规则通俗解释👇:
-
ArrayList() 默认初始容量是 0
- 刚开始你创建一个空的 ArrayList,它像一个空的背包,没有空间。💼
- 但是!当你第一次往里面放东西时,背包就会立刻扩容,容量变为 10!🎉 相当于它自动变大到可以放 10 个元素的大小。
ArrayList<String> list = new ArrayList<>(); // 初始容量为0 list.add("Apple"); // 第一次添加元素时扩容到 10
-
指定初始容量
- 如果你知道你需要存放多少东西,比如你需要装大约 50 个水果🍎🍊,那么你可以一开始就指定这个背包的容量为 50,这样它就不会频繁地扩容。
ArrayList<String> list = new ArrayList<>(50); // 指定初始容量为50
-
使用现有集合创建 ArrayList
- 假设你手里已经有一个装满了东西的小箱子📦,比如另一个集合
Collection
,你要用这个箱子的东西来创建 ArrayList。这时,ArrayList 的初始容量会根据这个箱子的大小自动设置。💡
List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Orange")); // 初始容量会根据这个集合的大小自动设置为 3
- 假设你手里已经有一个装满了东西的小箱子📦,比如另一个集合
-
第一次扩容
- 如果你没指定容量,也没有用现有集合,那么第一次扩容就会直接扩到 10 个元素的容量📏。
举例:刚开始是 0,一旦你添加第一个元素,容量直接膨胀到 10 个单位。🎈
list.add("Apple"); // 背包从 0 扩容到 10
- 如果你没指定容量,也没有用现有集合,那么第一次扩容就会直接扩到 10 个元素的容量📏。
-
后续的扩容规则🔄
-
当你的背包装满 10 个东西后,你继续往里面放东西时,背包会按照
1.5倍
的速度变大。📦 就像打气球🎈,每次都会膨胀一点:
- 第一次扩容: 容量从 10 -> 15
- 第二次扩容: 容量从 15 -> 22
- 第三次扩容: 容量从 22 -> 33
举例:
list.add("Apple"); list.add("Banana"); ... // 加到第10个元素 list.add("Orange"); // 现在背包扩容到15了!
-
-
批量添加元素
- 当你使用
addAll()
方法一次性添加很多东西时,ArrayList 会根据需要的数量自动扩容,确保一次性能够装下所有东西💼。 - 它会选择一个合适的容量,比如要装 12 个元素时,它会扩容到 Math.max(10, 12)。
- 当你使用
扩容是如何实现的?🛠️
扩容的背后其实很简单!每当容量不够时,ArrayList 会创建一个新的、更大的数组📚,然后把原来数组里的所有数据复制到新的数组里。旧的数组就会被垃圾回收掉,不用担心内存浪费。🧹
通俗解释 💡✨
想象一下你有一个弹性背包🎒,你可以往里面装东西。刚开始这个背包非常小,没有任何东西(容量为 0)。一旦你开始往里面装水果🍎🍌,背包就会自动变大,最初会膨胀到可以装下 10 个水果的大小。
每次你往背包里装满了 10 个水果,再想多放几个时,背包不会直接爆掉💥,它会自动扩展到之前大小的 1.5 倍。比如,装了10个水果后再加水果,背包会扩容到能装下 15 个,然后装满 15 个后,再扩容到能装 22 个🍇🍉。
如果你有很多东西一次性需要放进去,比如你有一个装满东西的小箱子📦,你想把这些东西全部转移到背包里,这时背包就会根据小箱子的大小直接扩容到合适的大小,确保你一次就能全部装进去。
简单总结💡:
- 默认初始容量是 0,第一次添加元素时扩到 10。
- 每次扩容的规则 是增加到上次容量的 1.5倍,比如 10 -> 15 -> 22 -> 33 这样逐步扩容。
- 指定容量或者批量添加时,ArrayList 会根据需要扩容到合适的大小。