深入剖析 ArrayList 扩容机制,揭开 Java 集合类库的秘密
2023-12-18 06:47:05
ArrayList 扩容:深入理解 ArrayList 的容量管理
什么是 ArrayList 扩容?
想象一下 ArrayList 就如同一个装有物品的袋子。当我们不断往袋子里添加物品时,总会有一个时刻袋子装满了。为了容纳更多的物品,我们需要一个更大的袋子。这正是 ArrayList 扩容所做的事情。当 ArrayList 达到其容量极限时,它会创建一个新的、更大的数组来存储元素。
扩容机制
ArrayList 使用数组来存储元素。当数组已满时,扩容过程便会触发。ArrayList 会创建一个新数组,大小根据现有数组的大小而定。如果现有数组的大小小于 50%,新数组的大小将是现有数组大小的两倍。如果现有数组的大小大于或等于 50%,新数组的大小将是现有数组大小的 1.5 倍。
扩容步骤
- 检测扩容时机: 当 ArrayList 达到容量极限时,它会调用扩容方法。
- 计算新数组大小: 新数组的大小根据现有数组的大小计算得出。
- 复制元素: ArrayList 将现有元素复制到新数组中。
- 更新引用: ArrayList 将引用指向新数组。
- 释放旧数组: 旧数组被垃圾回收器回收。
扩容示例
以下代码展示了 ArrayList 扩容的实际应用:
ArrayList<Integer> list = new ArrayList<>();
// 向 ArrayList 中添加元素
for (int i = 0; i < 10; i++) {
list.add(i);
}
// 打印 ArrayList 的大小
System.out.println("ArrayList size: " + list.size());
// 扩容 ArrayList
list.ensureCapacity(20);
// 打印 ArrayList 的大小
System.out.println("ArrayList size: " + list.size());
输出:
ArrayList size: 10
ArrayList size: 20
如你所见,最初 ArrayList 的大小为 10,当我们扩容到 20 时,ArrayList 创建了一个新数组并更新了引用。
避免频繁扩容
频繁扩容会影响 ArrayList 的性能。为了避免这种情况,ArrayList 采取以下措施:
- 延迟扩容: 当 ArrayList 达到容量极限时,它不会立即扩容,而是等待下一个添加或删除操作后再扩容。
- 预分配空间:
ensureCapacity()
方法允许我们预先为 ArrayList 分配一定的空间,从而避免在添加元素时频繁扩容。
结论
ArrayList 扩容机制对于确保 ArrayList 有效存储和检索元素至关重要。通过在必要时扩大数组的大小,ArrayList 避免了频繁的扩容,从而提高了其性能。扩容机制是 Java 集合框架设计中一个深思熟虑的组成部分,它使集合能够高效地处理大型数据集。
常见问题解答
1. ArrayList 的默认初始容量是多少?
答:10
2. 为什么 ArrayList 在扩容时不总是将数组大小增加一倍?
答:因为这会导致频繁的扩容,从而降低性能。
3. ensureCapacity()
方法的作用是什么?
答:ensureCapacity()
方法允许我们预先为 ArrayList 分配一定的空间,从而避免在添加元素时频繁扩容。
4. ArrayList 扩容时是否会保留现有元素?
答:是的,扩容时 ArrayList 会将所有现有元素复制到新数组中。
5. ArrayList 扩容后,旧数组会发生什么?
答:旧数组会被垃圾回收器回收。