首页 > 解决方案 > RandomAccess 接口如何在内部工作?

问题描述

据我了解,这个 RandomAccess 接口提供了在恒定时间内检索数据的能力。这个功能是如何实现的?有没有散列技术?

提前致谢

标签: java

解决方案


你的理解是错误的。RandomAccess可能提供一个承诺,但它不提供任何能力。提供能力取决于实现类。实际上RandomAccess在任何意义上都没有“在内部工作”,它没有任何功能。

文档中,它称为指示,而不是承诺:

实现使用的标记接口List表明它们支持快速(通常是恒定时间)随机访问。

实现的类RandomAccess通常通过将其内容存储在数组中来提供恒定时间访问。数组查找需要固定的时间。(根据文档,实现接口的类包括ArrayListAttributeListCopyOnWriteArrayListRoleList、和。当然也有一些第三方类也实现了它。)RoleUnresolvedListStackVector

编辑:阵列中的快速访问依赖于硬件。计算机可以在恒定时间内访问任何存储单元(存储单元)。阵列元素布置在连续的存储单元中。因此,如果您知道一个数组是从地址 54321 开始布局的,并且您需要访问索引 35 处的数组元素,则将这两个数字相加并知道该元素位于内存地址 54356(我忽略了单词中的轻微复杂性)大小通常为 8 个字节,地址的粒度为 1 个字节)。无论是JVM解释字节码还是方法已经编译为本机代码,原理都是一样的,从而绕过了JVM。您的搜索引擎应该会提供比我在这里给出的更好的解释。

对于没有任何内部工作的接口来说这是相当普遍的,但将其留给实现接口的类(如前所述,从 Java 8 和 9 开始,情况变得更加模糊,但在这方面RandomAccess仍然保持经典设计)。接口的工作是指定行为,而实现类的工作是提供它。

编辑:

从文档中,“这个接口的主要目的是允许通用算法改变它们的行为,以便在应用于随机或顺序访问列表时提供良好的性能”。为什么在这里提到它作为算法?

“通用算法”是指您和我编写的算法,这些算法适用于可能具有或不具有快速元素访问(可能实现也可能不实现RandomAccess)的列表。所以你可以写例如:

public void yourMethod(List<String> param) {
     if (param instanceof RandomAccess) {
          // do your work relying on fast element access
     } else {
         // do your work in some other way that doesn’t depend on fast element access
         // for example by iterating sequentially through the list
         // or copying the elements to a faster list implementation first.
     }
}

所以不,它与不同的 JVM 实现无关。


推荐阅读