为什么ArrayList实现RandomAccess接口?

ArrayList实现RandomAccess接口。 RandomAccess接口没有方法。 当我检查LinkedList它没有实现RandomAccess接口。

那么在ArrayList情况下,实现它有什么意义呢?

没有方法的接口在Java中称为标记接口。

根据RandomAccess的JavaDoc:

List实现用于指示的标记接口
他们支持快速(通常是恒定时间)随机访问。

有关更多信息,请查看两个JavaDoc页面。

http://docs.oracle.com/javase/6/docs/api/java/util/RandomAccess.html

http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html

RandomAccess接口没有方法

这称为标记接口,是一种称为标记接口模式的设计模式 。

当我检查LinkedList时,它没有实现RandomAccess接口。 那么在ArrayList的情况下,实现它有什么意义呢?

因为LinkedList随机访问是O(n),而它是ArrayList的O(1)。

它在文档中说明 :

操作随机访问列表(例如ArrayList)的最佳算法在应用于顺序访问列表(例如LinkedList)时会产生二次行为

这似乎在文档中有很好的描述: http : //docs.oracle.com/javase/7/docs/api/java/util/RandomAccess.html

List实现使用的RandomAccess Marker接口, 表示它们支持快速(通常是恒定时间)随机访问 。 此接口的主要用途是允许通用算法更改其行为,以便在应用于随机或顺序访问列表时提供良好的性能。 当应用于顺序访问列表(例如LinkedList)时,用于操纵随机访问列表(例如ArrayList)的最佳算法可以产生二次行为。 鼓励使用通用列表算法来检查给定列表是否是此接口的实例,然后应用将在应用于顺序访问列表时性能较差的算法,并在必要时更改其行为以保证可接受的性能。

人们认识到随机和顺序访问之间的区别通常是模糊的。 例如,一些List实现提供渐近线性访问时间,如果它们变大,但实际上是持续访问时间。 这样的List实现通常应该实现这个接口。 根据经验,如果对于类的典型实例,此循环,List实现应实现此接口:

  for (int i=0, n=list.size(); i < n; i++) list.get(i); 

运行速度比这个循环快:

  for (Iterator i=list.iterator(); i.hasNext(); ) i.next(); 

1)有两个类实现RandomAccess接口。 他们是:

 ArrayList (Part of List) Vector (Part of List) 

2) RandomAccess接口的目的是以相同的速度检索Collection中的任何随机元素。 示例:我有一百万个对象的集合。 实现RandomAccess接口使您有时间检索第10个元素和17869个元素。 这使得ArrayListVector更加强大。

3) RandomAccess接口没有方法或字段,也称为标记接口。 这些用于向编译器指示某些内容,换句话说,实现这些接口意味着对实现类的某些特殊处理。

让我们看看如何实际使用这个标记界面。 首先是文档中的相关部分(粗体是我的强调)。

List实现使用的标记接口,表示它们支持快速(通常是恒定时间)随机访问。 此接口的主要用途是允许通用算法更改其行为,以便在应用于随机或顺序访问列表时提供良好的性能。 List实现使用的RandomAccess Marker接口,表示它们支持快速(通常是恒定时间)随机访问。 此接口的主要用途是允许通用算法 更改其行为,以便在应用于随机或顺序访问列表时提供良好的性能 。 当应用于顺序访问列表(例如LinkedList)时,用于操纵随机访问列表(例如ArrayList)的最佳算法可以产生二次行为。

我们来举个例子吧。 假设您正在编写排序等算法的通用实现,并且您正在选择快速排序,就像您想要就地排序一样。 为什么通用 ? 因为您可能希望算法能够在各种List上使用合理且可预测的性能特征(有很多种类 – 不是)。 因此,您的算法函数将列表作为输入并返回与排序相同的列表。 暂时不要考虑影响快速排序性能的各种因素(例如已排序的数据,重复数据,正确的枢轴选择等)。 除了数据/排序的上述特征之外,另一个关键点是你的算法让我们厌倦了遍历列表 – 在这种情况下,它会大量使用随机访问,因为它需要比较和交换元素。 那么您的想法是什么 – 您的算法在所有类型的List实现上都能表现良好。 想想LinkedList – 在API中有一个随机访问的规定,但它需要大量的遍历,因为数据在列表中的组织方式是指向彼此的节点以及经历大量节点的痛苦不可避免的行为到达一个随机节点。 因此,您的通用算法在性能方面具有更多可变性。 如果你知道某些列表提供快速的ramdom访问而有些列表没有,那该怎么办? 如果有一个标记,那该怎么办? 随之而来的是“RandomAccess”标记接口,它通过ArrayList实现(标记/注释将是更好的单词),以指示(您的代码通常会检查RandomAccess测试的实例 ),随机访问它的数据非常快,您可以依赖它编写一个执行的算法,如果某个列表没有,则尝试替代算法,或者可能先将其转换为ArrayList,或者最坏的情况下完全拒绝这样的输入。

doc的另一部分通过提供两种不同的方式来访问基础数据,这是很容易理解的。 快速随机访问意味着第一次运行速度比第二次快。

 for (int i=0, n=list.size(); i < n; i++) list.get(i); runs faster than this loop: for (Iterator i=list.iterator(); i.hasNext(); ) i.next(); 

RandomAccess:标记界面

java.util.RandomAccess – 自JDK 1.4以来,集合框架的成员。 Implemetations:ArrayList和CopyOnWriteArrayList。

用于随机访问数据(索引基础)

List实现使用的标记接口,表示它们支持快速(通常是恒定时间)随机访问。 此接口的主要用途是允许通用算法更改其行为,以便在应用于随机或顺序访问列表时提供良好的性能。

当应用于顺序访问列表(例如LinkedList)时,用于操纵随机访问列表(例如ArrayList)的最佳算法可以产生二次行为。

鼓励使用通用列表算法来检查给定列表是否是此接口的实例,然后应用将在应用于顺序访问列表时性能较差的算法,并在必要时更改其行为以保证可接受的性能。

人们认识到随机和顺序访问之间的区别通常是模糊的。

如果对于类的典型实例,此循环应该实现此接口:

 for (int i=0, n=list.size(); i < n; i++) list.get(i); runs faster than this loop: for (Iterator i=list.iterator(); i.hasNext(); ) i.next(); 

有关更多信息,请参阅我的博客:
http://javaexplorer03.blogspot.in/2015/07/randomaccess-java.html

RandomAccess接口表示对Collection元素的有效随机访问

在客户端代码中,您可以检查集合是否是RandomAccess的实例,然后仅执行随机访问操作。

可以随机访问LinkedList和ArrayList中的元素,但ArrayList复杂度为O(1),LinkedList为O(n)。