LinkedList是双向链表,get(i)为O(n);ArrayList是连续数组,get(i)为O(1),故RandomAccess接口仅作标记;应通过instanceof判断后选择for或迭代器遍历。
看懂底层结构,才能选对遍历方式
LinkedList 是双向链表,每个节点存数据 + 前驱指针 + 后驱指针;访问第
i
个元素必须从头或尾开始逐个跳转,
get(i)
时间复杂度是 O(n)。而 ArrayList 是数组,内存连续,通过索引可直接计算地址,
get(i)
是 O(1) —— 这就是 RandomAccess 接口存在的根本原因:它不提供方法,只标记“支持快速随机访问”。
用 instanceof 判断是否支持 RandomAccess
别硬记哪个类该用哪种循环,运行时判断最稳妥:
if (list instanceof RandomAccess)
→ 用普通 for 循环(
else
→ 用增强 for 或显式 Iterator(
或
)
这个判断在工具方法、泛型集合处理中非常实用,避免把 LinkedList 当 ArrayList 用导致性能暴跌。
实测差距远超想象:100 万数据下典型耗时
以真实测试为依据(JDK 17+,HotSpot,禁用 JIT 预热干扰):
Postman Mac版
Postman Mac版是一款专为macOS设计的API开发与测试工具,凭借简洁的界面和强大的功能,深受开发者喜爱。它支持发送各种HTTP请求(GET、POST、PUT等),轻松管理接口集合、环境变量和模拟服务器。Mac用户可享受原生性能、快捷键优化及与系统无缝集成的体验,适用于接口调试、自动化测试和文档生成。无论是个人项目还是团队协作,Postman for Mac都能提升API开发效率,是macOS上不可或缺的接口工作台。
下载
ArrayList(RandomAccess)
:
– 普通 for:≈ 4.5 ms
– 增强 for / Iterator:≈ 6.2–7.0 ms
LinkedList(非 RandomAccess)
:
– 普通 for(含 get(i)):≈ 140–180 ms(因每次 get 都要遍历链表)
– 增强 for / Iterator:≈ 9–11 ms(迭代器直接沿 next 指针走,O(1) 移动)
注意:增强 for 对 LinkedList 来说,本质就是调用 iterator,不是语法糖的“慢”,而是底层适配得好。
特殊场景别踩坑:边遍历边修改怎么办
如果遍历中需要删除当前元素或插入到当前位置附近:
ArrayList:优先用
Iterator.remove()
,避免并发修改异常;但 remove(i) 会触发数组搬移,开销大
LinkedList:它的
ListIterator
支持
、
、
,全部是 O(1),这才是它不可替代的优势场景——比如解析日志流时动态过滤+插桩
此时哪怕用的是 LinkedList,也别用 for + get(i) 再 remove(i),那等于双重 O(n)。
for (int i = 0; i )for (E e : list)Iterator it = list.iterator(); while(it.hasNext()) it.next(); add()remove()set()