为什么 Java List 接口不支持 getLast()?

2022-09-02 21:04:46

我试图理解Java标准集合库中的API不一致。

List 或 AbstractList 中没有获取最后一项的方法,尽管可以使用 size 和 getIndex() 来模拟它。

但是,LinkedList支持该功能。

任何想法为什么决定不支持这种方法在接口?


答案 1

该接口不支持,因为设计人员选择了“最小接口”。通过定义最少的方法,它使其更容易理解和更快地学习。java.util.ListgetLast()

这与“人道接口”(例如在Ruby数组类中使用)相反,后者试图提供用于执行常见操作的方法(例如)。由于有许多用途,像列表这样的基本概念可以放在一起,这往往会导致更大的接口。getLast()

有关更多信息,请参阅Martin Fowler的最小界面Humane界面描述。

至于为什么LinkedList支持等,引用javadoc的话:getLast()

...LinkedList 类提供了统一命名的方法,用于在列表的开头和结尾获取、删除和插入元素。这些操作允许将链接列表用作堆栈、队列或双端队列 (deque)。

据推测,对于这些特定用例,一般列表是不够的。

作为对Java Collections API首席设计师(Joshua Bloch)思想的洞察,他提供了他工作的API设计格言列表。其中,与这个问题最相关的是:

API 的早期草稿应简短,通常为一页,其中包含类和方法签名以及一行说明。这样,当您第一次没有正确调整 API 时,可以轻松重构 API。

如有疑问,请将其排除在外。如果有API设计的基本定理,那就是它。它同样适用于功能、类、方法和参数。API 的每个方面都应该尽可能小,但不能变小。您始终可以在以后添加内容,但不能将其删除。最小化概念权重比类或方法计数更重要。

保持 API 没有实现细节。它们使用户感到困惑,并抑制了进化的灵活性。实现细节并不总是显而易见的:警惕过度指定。

最小化可访问性;如有疑问,请将其保密。这简化了 API 并减少了耦合。

考虑 API 设计决策的性能后果,但不要扭曲 API 以实现性能提升。幸运的是,好的API通常适合快速实现。

然而,他也说:

不要让客户端执行库可以执行的任何操作。违反此规则会导致客户端中的样板代码,这很烦人且容易出错。

这只是表明设计指南经常发生冲突,API设计人员工作中最困难的部分是平衡这些冲突。


答案 2

通常原因是他们想用Big-O要求指定每个函数,并认为getLast()不能在所有列表上有效地实现。因此,他们在每个级别上都引入了Big-O承诺。

或者它可能只是一个疏忽,或者他们觉得它不够普遍,如果你需要它,你可以用大小/getIndex得到它。