ArrayList随机访问快(O(1))、尾插接近O(1)且更稳;LinkedList头插/删极快(O(1)),但随机访问慢(O(n))、内存开销大;中间操作胜负取决于是否已定位位置。

随机访问快、插入删除慢——这是数组和链表的经典印象,但放到 Java 的 ArrayList 和 LinkedList 上,不能只看理论,得看实际场景下的量化表现。
随机访问:ArrayList 稳压 LinkedList 十倍以上
ArrayList 底层是连续数组,get(i) 直接计算内存偏移,时间复杂度稳定 O(1)。LinkedList 每次 get(i) 都要从头或尾开始遍历,平均需走 n/2 个节点,时间复杂度 O(n)。
实测数据(10 万元素,随机取 1 万个索引):
- ArrayList 平均耗时约 0.8 ms
- LinkedList 平均耗时约 12–15 ms(随数据量增长线性变慢)
- 当元素达百万级,差距可拉大到 30 倍以上
原因不只是算法复杂度:CPU 缓存预取对连续内存友好,ArrayList 天然受益;而 LinkedList 节点分散在堆中,频繁缓存未命中,进一步拖慢访问速度。
立即学习“Java免费学习笔记(深入)”;
尾部插入:两者接近,ArrayList 略优
两者在末尾添加元素都可做到摊销 O(1):
- ArrayList 尾插:多数情况直接写入,扩容时复制数组带来瞬时开销(但 1.5 倍扩容策略让摊销成本极低)
- LinkedList 尾插:有
last指针,新建节点 + 改指针,纯 O(1)
实测(100 万次 add 到空列表):
- ArrayList:约 45–50 ms
- LinkedList:约 55–65 ms(对象分配 + 指针赋值开销略高)
小数据量(如千级)下 LinkedList 可能略快,但中大规模下 ArrayList 更稳。
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
头部插入/删除:LinkedList 明显占优
ArrayList 在开头 add(0, x) 或 remove(0),必须把全部后续元素整体平移,O(n) 开销肉眼可见。
LinkedList 只需调整 first 指针与新节点的连接,O(1) 完成。
实测(10 万次头插):
- ArrayList:约 1800–2200 ms
- LinkedList:约 8–12 ms
差距超百倍。若业务逻辑涉及大量队列式入队(如消息缓冲)、栈式操作(push/pop),LinkedList 在这里不可替代。
中间插入/删除:位置决定胜负
关键前提:你是否已经持有目标位置的引用?
- 若靠索引操作(如
list.add(5000, x)):两者都要先“找位置”——ArrayList 查索引是 O(1),但插入仍要挪动后半段;LinkedList 查索引是 O(n),插入本身 O(1)。综合下来,ArrayList 通常更快(尤其中前段) - 若已有迭代器定位(
ListIterator),比如边遍历边删:LinkedList 插入/删除真正达成 O(1),ArrayList 仍需移动,此时 LinkedList 显著胜出
例如,在遍历过程中删除符合条件的元素(非固定索引):
使用 iterator.remove() 时,LinkedList 耗时约为 ArrayList 的 1/5~1/3。
不复杂但容易忽略:选型不是比“哪个快”,而是看你的操作模式分布——读多?写多?在哪写?有没有现成位置引用?结合这些再看数字,才真正有用。









