跳转至

RandomAccess 空接口有什么作用?

结论

RandomAccess 是一个标记接口(marker interface),没有任何方法,用于标识该 List 是否支持快速随机访问(通常指 O(1) 的 get(i))。

源码

public interface RandomAccess {
}

空接口,纯标记。

哪些 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#binarySearchCollections#indexedBinarySearch 都用了这个判断:

if (list instanceof RandomAccess || list.size() < BINARYSEARCH_THRESHOLD)
    return indexedBinarySearch(list, key);
else
    return iteratorBinarySearch(list, key);

设计思想

这是典型的标记接口 + instanceof 判断模式,和 SerializableCloneableRemote 一样,靠"是否实现接口"传递元信息给算法/框架。现代 Java 也可以用注解替代,但 RandomAccess 已是历史约定。