为什么 Collections 类包含独立(静态)方法,而不是将它们添加到 List 接口中?

发布于 2024-09-06 16:12:07 字数 598 浏览 1 评论 0原文

对于 Collections 中的所有方法List 作为他们的第一个参数,为什么这些方法不就是 List 接口的一部分吗?

我的直觉是:给定一个 List 对象,该对象本身应该“知道”如何对其自身执行操作,例如rotate()、shuffle() 或reverse()。但相反,作为一名 Java 程序员,我必须检查 List 接口中的方法以及 Collections 类中“那边”的静态方法,以确保我使用规范的解决方案。

为什么某些方法作为静态独立方法放置在 Collections 类中,而不是添加到 List 接口中(并且可能因此由某些现有或可能的基类实现)?

我试图更好地理解 Java 集合框架背后的设计决策。

这里是否有一些我忽略的引人注目的 OO 设计原则?或者这种区别只是出于某些实际的性能原因?

For all the methods in Collections that take a List as their first argument, why aren't those methods simply part of the List interface?

My intuition is: given a List object, that object itself should "know" how to perform on itself operations such as rotate(), shuffle(), or reverse(). But instead, as a Java programmer, I have to review both the methods in the List interface, as well as the static methods "over there" in the Collections class, to ensure I'm using a canonical solution.

Why were some methods placed as static standalone methods in the Collections class, instead of being added to the List interface (and presumably thus implemented by some existing or would-be base class)?

I'm trying to better understand the design decisions behind the Java collections framework.

Is there some compelling OO design principle here that I'm overlooking? Or was this distinction done simply for some practical, performance reason?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

_失温 2024-09-13 16:12:07

关键是,给定合适的原始操作(删除、设置等),可以实现一次更高级的操作(排序、随机播放、二分搜索),而不是由每个列表实现来实现。

实际上,java.util.Collections 就像 .NET 的 Enumerable 类 - 充满了可以在任何集合上工作的通用方法,以便它们可以共享单个实现并避免重复。

The point is that given suitable primitive operations (remove, set etc) a bunch of more high level operations (sort, shuffle, binary search) can be implemented once rather than being implemented by every single list implementation.

Effectively, java.util.Collections is like .NET's Enumerable class - full of general purpose methods which can work on any collection, so that they can share a single implementation and avoid duplication.

ヅ她的身影、若隐若现 2024-09-13 16:12:07

List 接口方法背后的理性

  1. List 接口是 Java 运行时的一个非常核心的部分,并且在推出您自己的 List 实现时完全实现所有成员已经有点繁重。因此,添加与列表定义不直接相关的额外方法有点无关紧要。如果您需要 List 实现上的这些方法,为什么不子类化接口然后需要它们呢?
  2. 如果您打算在 1.3 版本中通过添加新的实用方法来向 List 接口添加功能,那么您将破坏该接口的所有过去的实现者。
  3. 从领域驱动设计的角度来看,集合中的实用方法不是列表的正常域的一部分。
  4. 关于 OO 设计原则,我认为区分应用程序 OO 设计和语言运行时 OO 设计非常重要。

Java 的作者们现在可能会以非常不同的方式做事,因为他们对 API 的多年使用有了后见之明和看法。也就是说,C# IList 接口与 Java 非常相似,并且 C# 的作者确实有这样的观点。

Rational Behind the List Interface's Methods

  1. The List interface is a very core part of the Java runtime and is already a little onerous to fully implement all of the members when rolling out your own List implementations. So, adding extra methods that aren't directly related to the definition of a list is a bit extraneous. If you need those methods on a List implementation, why not subclass the interface and then require them?
  2. If you where going to come along say in version 1.3 and add functionality to the List interface by adding new utility methods, you will break all past implementors of the interface.
  3. From a Domain-Driven Design perspective, the utility methods in Collections are not part of the normal domain of a list.
  4. Regarding OO design principals, I think it would be important to make the distinction between application OO design and language runtime OO design.

The authors of Java may do things very differently now that they have hindsight and perspective of many years of usage of the API. That said the C# IList interface is quite similar to Java's and C#'s authors did have the perspective.

缘字诀 2024-09-13 16:12:07

这在某种程度上肯定是一个判断。我认为要考虑的主要权衡是:当您向接口添加方法时,该接口的每个实现者都必须编写代码来实现它。

如果该方法的语义使得接口的不同实现最好以非常不同的方式实现这些语义,那么最好将其放入接口中。 (当然,如果语义根本无法根据接口中的其他方法来定义,那么它必须是接口中它自己的方法。)

另一方面,如果语义是这样它们就可以根据接口中的其他方法来定义,并且接口的实现者只会一遍又一遍地编写相同的代码,那么最好创建一个实用方法,将接口的实例作为争论。

It's certainly a judgement call at some level. I think the main trade-off to consider is this: When you add a method to an interface, every implementer of that interface must write code to implement it.

If the semantics of that method are such that different implementations of the interface will best implement those semantics in very different ways, then it's better to put it in the interface. (Of course, if the semantics simply can't be defined in terms of other methods in the interface, then it must be its own method in the interface.)

On the other hand, if the semantics are such that they can be defined in terms of other methods in the interface, and implementers of the interface will just tend to write the same code over and over again, then it's better to make a utility method that takes an instance of the interface as an argument.

吐个泡泡 2024-09-13 16:12:07

它们是实用方法,而不是核心列表功能。如果您添加了可以在列表上执行的所有可能的操作,则列表界面只会变得臃肿。 Collections 中的操作不需要了解 List 的内部结构,它们在公共接口上进行操作,因此可以愉快地生活在外部类中。

They are utility methods and not core List functionality. The List interface would just get bloated if you added every possible operation you could do on a List. And the operations in Collections do not need to know about the internals of a List, they operate on the public interface so can happily live in an external class.

蓝眸 2024-09-13 16:12:07

这里有两个解释:

  1. 历史:Collections类是在List接口之后创建的。设计人员选择保留现有接口的向后兼容性。否则很多开发人员将不得不更改他们的代码。

  2. 逻辑:您正在讨论的方法不需要有关列表实现的内部知识,并且可以在实现它的任何集合上实现。

There are two explanations here:

  1. Historical: Collections class was created after List interface. Designers chose to preserve backward compatibility of already existing interface. Otherwise a lot of developers would have to change their code.

  2. Logical: The methods you are talking about do not require internal knowledge on List implementation and can be implemented over ANY collection implementing it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文