RandomAccess 是标记接口,表明 List 支持 O(1) 随机访问;ArrayList 实现它因数组支持快速索引,LinkedList 不实现因链表 get(i) 为 O(n),影响遍历策略选择。

RandomAccess 接口本身不提供任何方法,它只是一个标记接口(Marker Interface),作用是告诉 JVM 或调用方:这个 List 实现支持 O(1) 时间复杂度的随机访问。 它不改变代码行为,但能影响遍历策略的选择——尤其在使用 Collections 工具类或某些框架内部逻辑时,会据此决定用 for 循环还是迭代器。
为什么需要 RandomAccess?
不同 List 实现的底层结构差异很大:
- ArrayList 基于数组,通过索引 get(i) 是直接内存寻址,快;
- LinkedList 是双向链表,get(i) 需要从头或尾开始逐个跳转节点,最坏 O(n);
如果统一用 for (int i = 0; i
哪些 List 实现了 RandomAccess?
标准库中明确实现该接口的有:
- ArrayList
- CopyOnWriteArrayList
- Stack(继承自 Vector)
- Vector
而 LinkedList、AttributeList、RoleList 等未实现——它们更适合用迭代器遍历(for-each 或显式 Iterator)。
如何利用 RandomAccess 优化遍历?
不是手动判断,而是依赖已有机制:
- Collections.binarySearch():内部先检查是否 instanceof RandomAccess,再决定是否用索引二分(否则退化为顺序扫描);
- Collections.sort():对 RandomAccess 列表优先用 Arrays.sort() + 数组拷贝,非 RandomAccess 则转成数组再排;
- 你自己写通用工具方法时,可模仿这种风格:
if (list instanceof RandomAccess) {
for (int i = 0; i < list.size(); i++) {
process(list.get(i));
}
} else {
for (Object item : list) {
process(item);
}
}
注意:for-each 并不总是最优
for-each 编译后本质是 Iterator,对 ArrayList 来说,它比普通 for 略慢(多一次对象创建和方法调用开销);但在多数业务场景中差异微乎其微。真正要注意的是:别在 LinkedList 上写 for (int i = 0; i


















