ArrayList 的扩容机制解析

简介: ArrayList扩容机制解析:添加元素时先检查容量,不足则触发扩容。默认初始容量为10,每次扩容1.5倍,通过数组拷贝实现,耗时O(n)。频繁扩容影响性能,建议预估容量并初始化指定大小,提升效率。


ArrayList 是 Java 中最常用的动态数组实现,其核心优势在于自动扩容——无需预先指定容量,即可按需增长。但这一“便利”背后,有一套严谨的扩容逻辑。


一、添加元素时触发扩容检查

当我们调用 add(E e) 方法时,ArrayList 并不会直接将元素放入数组,而是先检查容量是否足够

public boolean add(E e) {
    ensureCapacityInternal(size + 1); // 检查并确保容量
    elementData[size++] = e;          // 赋值
    return true;
}

关键在 ensureCapacityInternal 方法。


二、扩容的核心逻辑

  1. 默认初始容量
    若使用无参构造(new ArrayList<>()),底层 elementData 初始为一个空数组。首次添加元素时,会初始化为容量 10
  2. 扩容规则size + 1 > 当前容量 时,触发扩容:
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容 1.5 倍
  • 例如:当前容量 10 → 扩容后为 15;
  • 若仍不够(如一次性添加大量元素),则直接扩容到所需最小容量。
  1. 数组拷贝
    扩容通过 Arrays.copyOf(elementData, newCapacity) 实现,创建新数组并将旧数据复制过去。这是一个 O(n) 操作,代价较高。

三、性能启示

  • 频繁扩容影响性能:每次扩容都涉及内存分配与数据拷贝;
  • 建议预估容量:若已知元素数量,使用 new ArrayList<>(initialCapacity) 初始化,避免多次扩容;
  • Guava 推荐Lists.newArrayListWithCapacity(100) 可读性更佳。

四、示例对比

// 不推荐:多次扩容
List<String> list1 = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    list1.add("item" + i);
}
// 推荐:一次到位
List<String> list2 = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
    list2.add("item" + i);
}

后者避免了约 10 次扩容(10 → 15 → 22 → 33 → ... → 1000),显著提升效率。


总结

ArrayList 的扩容机制以 1.5 倍增长平衡空间与时间开销,但在性能敏感场景下,主动指定初始容量是最佳实践。理解其底层原理,有助于写出更高效、更稳定的代码。


相关文章
|
13天前
|
数据采集 人工智能 安全
|
8天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
644 4
|
8天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
348 164
|
7天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
359 155

热门文章

最新文章