随机访问接口,为什么没有方法?

3
我正在阅读Collections.shuffle(List) javadoc,并查看RandomAccess javadoc

用于指示列表实现支持快速(通常是恒定时间)随机访问的标记接口。[...]

我想知道为什么这个接口(如Serializable)没有方法?这个设计有什么原因?
即使只有List“实现”了这个接口,为什么不将E get()设置为一个方法?我知道并不是每个列表都是随机访问的,但如果没有方法,我怎么能使用这个接口呢?
就像这样:
if(object instanceof RandomAccess){
    // should I cast it if no operations can be done? why?
}

此外,只有列表可以进行随机访问吗?文件呢?

正如javadoc所述,它是一个“标记”接口,根据定义不会有方法。它标记了具有快速随机访问的List实现,以便使用该实现的人们知道他们正在使用的类已经优化为执行此操作。 - Hovercraft Full Of Eels
2个回答

10
一个"标记"接口是一种早于注解的技术,它用于标记一个类符合某个标准,而该标准不涉及方法。
在这种情况下,对于不支持快速随机访问的列表,Shuffle可能会有所不同。想想如何洗牌一个链表; 很难,对吧?你不能只说“给我一个随机元素”,而不是遍历列表,跟随指针到下一个元素。现在将其与ArrayList进行对比。由于列表的存储方式,获取随机元素要容易得多。
在方法名中没有一种方法可以限定“列表的存储方式”或“不同访问模式的快慢”。因此,Java使用标记接口来提供此信息。
在这种情况下,ArrayList将是一个RandomAccess,而LinkedList则不是。
编辑
那些对标记接口和标记注解的区别感兴趣的人会喜欢Joshua Bloch的《Effective Java 2nd Edition》中的第37项:“使用标记接口定义类型”。

1
我认为拒绝接受列表对于实现洗牌方法的代码并不合适(因为它已经实现了一个接受列表的方法)。但是,它可能会为链表选择不同的算法(例如先复制列表,或执行不需要随机访问的算法)。 - Thilo
我认为,使用标记接口时,与其说是关于标准或契约,因为这涉及到方法反映的行为,不如说更多关于类的实现。否则,回答很棒。 - David Harkness
@CoryKendall 我仍然不清楚基本概念。为什么要实现RandomAccess?即使Array由于连续的内存提供更快的访问,而ArrayList在内部使用数组,那应该足以使它更快,我对吗?实现RandomAccess的列表是否有JVM执行额外的操作? - AKS

1

这是一个标记接口。它定义了一种行为或能力,不使用任何额外的方法。

在这种情况下,它表示随机访问(已在List接口中定义)不仅是可能的,而且还是高效的。使用List的代码可以根据此切换算法。

有人可能会争论这是否是一个好的设计决策。例如,随机访问方法可以从List中删除(只允许迭代),并放入RandomAccess接口中。同样,对象序列化系统的方法也可以放入Serializable接口中。

此外,只有列表可以进行随机访问吗?

我想这个接口也可以用于其他事情,但看起来目前只被列表使用。

文件呢?

有一个单独的机制用于对文件进行随机访问(java.io.RandomAccessFile)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接