RandomAccess 空接口有什么作用?¶
结论¶
RandomAccess 是一个标记接口(marker interface),没有任何方法,用于标识该 List 是否支持快速随机访问(通常指 O(1) 的 get(i))。
源码¶
空接口,纯标记。
哪些 List 实现了它¶
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable { ... }
public class java.util.Vector<E> ... implements RandomAccess { ... }
public class CopyOnWriteArrayList<E> ... implements RandomAccess { ... }
而 LinkedList 没有实现 RandomAccess,因为它底层是链表,get(i) 是 O(n)。
为什么需要它¶
算法在遍历 List 时,可以根据是否实现 RandomAccess 选择最优遍历方式:
if (list instanceof RandomAccess) {
// 随机访问型:用 for + get(i)
for (int i = 0; i < list.size(); i++) {
process(list.get(i));
}
} else {
// 顺序访问型:用迭代器或 for-each
for (E e : list) {
process(e);
}
}
JDK 源码中 Collections#binarySearch、Collections#indexedBinarySearch 都用了这个判断:
if (list instanceof RandomAccess || list.size() < BINARYSEARCH_THRESHOLD)
return indexedBinarySearch(list, key);
else
return iteratorBinarySearch(list, key);
设计思想
这是典型的标记接口 + instanceof 判断模式,和 Serializable、Cloneable、Remote 一样,靠"是否实现接口"传递元信息给算法/框架。现代 Java 也可以用注解替代,但 RandomAccess 已是历史约定。