ArrayList 随机访问快、插入慢?LinkedList 插入快、查找慢?这是真的吗?我们用 JMH 实测数据说话。

一、集合选型的常见误区

  • 1.1 “频繁插入删除用 LinkedList”——真的是这样吗
  • 1.2 “随机访问用 ArrayList”——没错,但有多快
  • 1.3 内存占用方面很多人忽略了

二、底层数据结构对比

  • 2.1 ArrayList——Object[] 数组,连续内存
  • 2.2 LinkedList——双向链表 Node,非连续内存
  • 2.3 内存布局图示

三、JMH 基准测试设置

  • 3.1 JMH 简介与基本注解
  • 3.2 测试环境说明(JDK 版本、JVM 参数)
  • 3.3 测试方法设计——头/尾/中间位置的增删查

四、随机访问性能对比

  • 4.1 get(index) 的 JMH 数据
  • 4.2 ArrayList O(1) vs LinkedList O(n) 的差异有多大
  • 4.3 数据量从 100 到 100 万的性能曲线

五、插入性能对比

  • 5.1 尾部插入:ArrayList 略快——LinkedList 的指针操作也不是零成本
  • 5.2 头部插入:LinkedList 更快——ArrayList 需要 System.arraycopy
  • 5.3 中间插入:差异取决于位置
  • 5.4 foreach 遍历性能:ArrayList 的缓存友好性

六、删除性能对比

  • 6.1 按索引删除 vs 按对象删除
  • 6.2 ArrayList 按对象删除需要先遍历

七、内存占用对比

  • 7.1 ArrayList 的内存——数组本身 + 预留容量
  • 7.2 LinkedList 的内存——每个节点 24~32 字节的额外开销
  • 7.3 相同数据量下的内存对比

八、选型决策指南

  • 8.1 什么时候选 ArrayList——80% 的场景
  • 8.2 什么时候选 LinkedList——频繁头插、不需要随机访问
  • 8.3 ArrayDeque vs LinkedList——双端队列的正确选择

九、总结

  • 实测数据表明:ArrayList 在绝大多数场景下优于 LinkedList
  • 选择集合时考虑三个维度:访问模式、数据量、内存敏感度