java - 为什么 Collections.synchronizedList(list) 在内部使用 instanceof 检查?

标签 java collections java-8

我正在检查 Collections 类的源代码。 我遇到了 Collections.synchronizedList(list)

方法
public static <T> List<T> synchronizedList(List<T> list) {
    return (list instanceof RandomAccess ?
            new SynchronizedRandomAccessList<>(list) :
            new SynchronizedList<>(list));
}

我不明白为什么我们要检查列表是否为 RandomAccess 类型。 我知道 ArrayList 实现了这个接口(interface),而 LinkedList 没有。

此外,SynchronizedRandomAccessList 继承SynchronizedList。 那么这个检查有什么意义呢? 请解释

最佳答案

你快到了。 Collections.synchronizedList(list) 检查 RandomAccess 因为一些列表实现了 RandomAccess 而其他列表没有。

这个 RandomAccess 是一个 marker interface ,就像 Serializable 一样。它告诉我们是否可以随机访问列表中的项目。 IE。从 ArrayList 中,我们可以检索具有相同计算成本的任何项目。另一方面,我们需要遍历 LinkedList 才能到达第 n 个元素。

那么,Collections.synchronizedList(list) 中发生了什么?它将 RandomAccess List-s 包装成一个 RandomAccess 同步列表,同时将非 RandomAccess 列表包装成一个非RandomAccess 同步列表。否则这些列表是相同的。下面是 SynchronizedRandomAccessList 的代码。这是 programming by difference 的一个很好的例子.这两个类几乎相同。

static class SynchronizedRandomAccessList<E>
    extends SynchronizedList<E>
    implements RandomAccess {

    SynchronizedRandomAccessList(List<E> list) {
        super(list);
    }

    SynchronizedRandomAccessList(List<E> list, Object mutex) {
        super(list, mutex);
    }

    public List<E> subList(int fromIndex, int toIndex) {
        synchronized (mutex) {
            return new SynchronizedRandomAccessList<>(
                list.subList(fromIndex, toIndex), mutex);
        }
    }

    private static final long serialVersionUID = 1530674583602358482L;

    /**
     * Allows instances to be deserialized in pre-1.4 JREs (which do
     * not have SynchronizedRandomAccessList).  SynchronizedList has
     * a readResolve method that inverts this transformation upon
     * deserialization.
     */
    private Object writeReplace() {
        return new SynchronizedList<>(list);
    }
}

您可能会问,RandomAccess 接口(interface)有什么意义?作为Holger指出,Collections.binarySearch() 基于此接口(interface)做出决定。另一个例子是 Collections.reverse()

关于java - 为什么 Collections.synchronizedList(list) 在内部使用 instanceof 检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47791308/

相关文章:

generics - 映射集合而不将它们转换为列表

java - 如何在 Java 8 中使用方法引用从非静态类调用非静态方法?

java - 如何限制 Java 8 应用程序消耗的总内存?

java - 为什么使用 Socket.setSoTimeout() 不起作用?

kotlin - 将两个状态流合并成新的状态流

java - 未送达邮件的原始邮件 header

java - 协变返回类型最佳实践

java - 当 Javadoc 标记不完整时,Maven 无法在 Java 8 中运行

java - 从 SQLiteDatabase 中删除一个元素是否会反射(reflect)其他元素 ID 的变化?

java - 使用 .concat 进行循环串联,而无需仅使用循环