简体   繁体   English

为什么像 Collections 类中的 sort 方法不在 List 接口中?

[英]Why methods like sort in Collections class are not in List interface?

Class Collections has some static methods as utilities to manipulate collections like List.类 Collections 有一些静态方法作为实用程序来操作 List 等集合。 For example the sort method (Collections.sort(list)).例如排序方法 (Collections.sort(list))。 I do not understand why Java specs made another class to host the sort method (and all the others like binarySearch) and not to List interface and concrete subclasses like ArrayList and LinkedList implement these methods.我不明白为什么 Java 规范创建另一个类来承载排序方法(以及所有其他类,如 binarySearch)而不是 List 接口和具体的子类,如 ArrayList 和 LinkedList 实现这些方法。

UPDATED更新

As I made a global research and read the answers from this post I have to say that (bird's eye view): Some people (I mention @dan,@WJS,@cdalxndr) said in this post, using the sort method as example, that because the sort of ArrayList and LinkedList can be done with the same way then we can implemented writing only one time.当我进行了全球研究并阅读了这篇文章的答案时,我不得不说(鸟瞰):有些人(我提到@dan,@WJS,@cdalxndr)在这篇文章中说,以排序方法为例,因为ArrayList和LinkedList的排序可以用同样的方式完成,所以我们可以实现一次只写一次。 So (I say) we could put the code in the List interface but until Java 7 we couldn't put any implementation in interface's body and the only way to write it one time was to implemented in utility class.所以(我说)我们可以把代码放在 List 接口中,但是直到 Java 7 我们不能把任何实现放在接口的主体中,一次编写它的唯一方法是在实用程序类中实现。 But since Java 8 interfaces has the feature of "default" method.但是由于 Java 8 接口具有“默认”方法的特性。 And Java team took advantage of this feature to have sort method implementation in interface level and that method can be used by ArrayList and LinkedList (as default if the classes do not override it) Java 团队利用这个特性在接口级别实现了 sort 方法,并且该方法可以被 ArrayList 和 LinkedList 使用(如果类没有覆盖它,则作为默认值)

Sorting is an algorithm, and List is a container.排序是一种算法, List是一个容器。

The developers wanted to separate list algorithms (sort, binary search, etc) from container logic (add, remove, etc) so they put the algorithms to the utility class Collections .开发人员希望将列表算法(排序、二分搜索等)与容器逻辑(添加、删除等)分开,因此他们将这些算法放在实用程序类Collections

Before Java 8, interfaces could not have default nor static methods, hence, every method added to the interface needed to be implemented by all classes implementing the interface.在 Java 8 之前,接口不能有defaultstatic方法,因此,添加到接口的每个方法都需要由实现该接口的所有类来实现。 Even when you provided a helpful implementation in a support class, the implementing class needed at least a delegating method.即使您在支持类中提供了有用的实现,实现类也至少需要一个委托方法。

So, unless you wanted to force all implementations to inherit from some abstract base class providing those methods, you had to be careful with what you add to the interface.因此,除非您想强制所有实现从提供这些方法的某个抽象基类继承,否则您必须小心添加到接口中的内容。

Even with the default methods, you have to be careful, to avoid polluting the name space of an implementing class with too many methods.即使使用default方法,您也必须小心,避免使用太多方法污染实现类的名称空间。 This might also be the reason why not every operation has been retrofitted to default methods in Java 8:这也可能是 Java 8 中并非每个操作都被改造成default方法的原因:

While adding a default method to an interface is less intrusive, as it does not create the need to implement it in already existing implementation classes, it may still cause a clash with a concrete method of the implementation class that didn't implement an interface method in the previous version.虽然向接口添加default方法的侵入性较小,因为它不需要在已经存在的实现类中实现它,但它仍然可能导致与未实现接口方法的实现类的具体方法发生冲突在以前的版本中。

Just imagine a custom List implementation in pre-Java 8 times that provided a helpful void sort(Comparator c) instance method just delegating to Collections.sort(this, c);想象一下 Java 之前 8 次的自定义List实现,它提供了一个有用的void sort(Comparator c)实例方法,只是委托给Collections.sort(this, c); . . That worked before Java 8, not improving the performance, but allowing to write list.sort(c);这在 Java 8 之前有效,没有提高性能,但允许编写list.sort(c); . . Nowadays, this method would unintentionally happen to override the default method with the same name and type, to which Collections.sort will delegate, producing an infinite loop (or rather, recursion).如今,此方法会无意中覆盖具有相同名称和类型的default方法, Collections.sort将委托给该方法,从而产生无限循环(或者更确切地说,递归)。

Still, the sort method has been added to the List interface, because of the immediate benefits.尽管如此, sort方法已添加到List接口中,因为它具有直接的好处。 Unlike the static methods in the Collections utility class, the default method can be overridden.Collections实用程序类中的static方法不同, default方法可以被覆盖。 This has been done for the most commonly used list types, ArrayList , Vector , and the implementation returned by Array.asList(…) .这已针对最常用的列表类型ArrayListVector以及Array.asList(…)返回的实现完成。 Since all those implementations are backed by an array, the overriding method can delegate to Arrays.sort using the backing array directly, whereas the default implementation will work with a temporary copy of the list contents.由于所有这些实现都由一个数组支持,因此覆盖方法可以直接使用支持数组委托给Arrays.sort ,而default实现将使用列表内容的临时副本。

It's also worth noting that those methods in Collections seem to be originally based on the assumption that those algorithms were suitable to all kind of implementations, which didn't hold.还值得注意的是, Collections中的这些方法最初似乎是基于这些算法适用于所有类型的实现的假设,但并不成立。 Two releases after the introduction of the Collection API, the RandomAccess marker interface was introduced, to tell two fundamentally different list implementation categories apart, so the static method could branch to two alternative algorithms based on it.在引入 Collection API 之后的两个版本中,引入了RandomAccess标记接口,以区分两个根本不同的列表实现类别,因此静态方法可以基于它分支到两种替代算法。

Whenever we have to branch based on the class we're operating on, we could question the abstraction and say that we might be better off with overridable methods on the type itself, but as explained above, there are historical reasons for the design and there still are reasons to be careful with adding methods to the interface.每当我们必须基于我们正在操作的类进行分支时,我们可以质疑抽象并说我们最好在类型本身上使用可覆盖的方法,但如上所述,设计有历史原因,并且仍然是在向接口添加方法时要小心的理由。

There is sort of an option since Java 8, just requires you to define (or use predefined comparator).几分,因为Java的8个选项,只需要你定义(或使用预定义的比较)。

Dummy example below:下面的虚拟示例:

    List<Integer> list = new ArrayList();
    list.addAll(List.of(1,5,4,3,6,8,9,2));

    list.sort(Comparator.naturalOrder());

But obviously it is not done the same way to you as an user as it is in Collections util (although I do believe that Collections implementation also wraps around using such comparator or something like it).但显然,作为用户,它不像在 Collections util 中那样以相同的方式完成(尽管我确实相信 Collections 实现也使用这样的比较器或类似的东西)。

Because it isn't necessary.因为没有必要。 All the following extend Collection以下所有扩展Collection

BeanContext, BeanContextServices, BlockingDeque<E>, BlockingQueue<E>,<br>
Deque<E>, EventSet, List<E>, NavigableSet<E>, Queue<E>, Set<E>,<br>
SortedSet<E>, TransferQueue<E>

So what you are advocating is that each interface provide the exact same implementation or perhaps a convenience method to each method in Collections .所以你提倡的是,每个接口都为Collections每个方法提供完全相同的实现或者可能是一个方便的方法。 That would be, imho, a form of code bloat.恕我直言,那将是一种代码膨胀。 In the former case, it would require changing multiple implementations if improvements were discovered.在前一种情况下,如果发现改进,则需要更改多个实现。

I know they added sort to the List interface, perhaps because it is such a common requirement.我知道他们在List接口中添加了sort ,也许是因为这是一个常见的要求。 But I never had a problem using Collections.sort to do sorting.但是我在使用Collections.sort进行排序时从来没有遇到过问题。 There may be other reasons of which I am unaware.可能还有其他我不知道的原因。

But I tend to think of Collections as very similar to the Math class.但我倾向于认为CollectionsMath类非常相似。 Double and Integer don't have duplicate math functions. DoubleInteger没有重复的数学函数。 Similar to Math , Collections is a utility that offers a variety of static methods that are usable by related classes.Math类似, Collections是一个utility ,它提供了各种可供相关类使用的静态方法。 Granted, the Math class is not in the Double or Integer, etc hierarchy , but its use is very similar.当然, Math类不在 Double 或 Integer 等hierarchy ,但其用法非常相似。

The designers of the Collections Framework (primarily Josh Bloch while working at Sun Microsystems ), as with many other sections of the Java API, had an eye to the longevity of the language. 集合框架的设计者(主要是在Sun Microsystems工作时的Josh Bloch ),与 Java API 的许多其他部分一样,都着眼于该语言的寿命。 Java incorporates the notion of sustainment and evolution of APIs directly into the syntax supported by the documentation with the @deprecated tag. Java 使用@deprecated标签将 API 的维持和演变的概念直接合并到文档支持的语法中。 Specifically, they anticipated additional sorting and searching algorithms would likely be developed over the years long before additional "container" operations would be discovered to add to the Collection , and List interfaces.具体来说,他们预计在发现额外的“容器”操作以添加到CollectionList接口之前,很可能会开发更多的排序和搜索算法。

They knew very well changes to the interfaces would impose upgrade requirements on development teams to deal with.他们非常清楚接口的变化会给开发团队带来升级需求。 Upgrade requirements slows the adoption of fixes and improvements that Sun Microsystems wanted teams to be able to absorb with ease.升级要求减缓了 Sun Microsystems 希望团队能够轻松吸收的修复和改进的采用。 Incorporating new methods for sorting and searching into the interface would greatly impede that goal;将用于排序和搜索的新方法合并到界面中将极大地阻碍该目标; placing an unnecessary burden on teams choosing to upgrade to the latest version of the Java language.给选择升级到最新版本 Java 语言的团队带来了不必要的负担。 Instead, they wisely chose to shunt these utility methods to a static utility class.相反,他们明智地选择将这些实用程序方法分流到静态实用程序类。

As with Java 8's List.sort(..) , I can only guess Oracle felt the pressures of the industry and other languages incorporating these common operations right into their collection itself.与 Java 8 的List.sort(..) ,我只能猜测Oracle感受到了行业和其他语言将这些常见操作直接纳入其集合本身的压力。 However, keeping these utilities separate from the collection minimizes adoption requirements they would impose on those who directly implement their interfaces.但是,将这些实用程序与集合分开可以最大限度地减少它们对直接实现其接口的人施加的采用要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么Collections类包含独立的(静态)方法,而不是将其添加到List接口? - Why does the Collections class contain standalone (static) methods, instead of them being added to the List interface? 为什么列出接口而不是类 - Why is List an Interface and not a Class 为什么填充,复制(dstList,srcList),shuffle,reverse,rotate Collections类方法只将List作为参数? - Why fill, copy (dstList, srcList), shuffle, reverse, rotate Collections class methods take only List as argument? 为什么集合排序方法不能在集合界面上使用 - Why collections sort Method cannot be used on set interface List 接口和 ArrayList 类:ensureCapacity() 和 trimToSize() 方法 - List Interface and ArrayList Class: ensureCapacity() and trimToSize() methods 从 class 到接口的实现方法作为链表 - Implementing methods from a class to a interface as a linked list 为什么对象类方法在接口中可用? - Why Object class methods are available in interface? 为什么我们不能创建Collections类的实例(不是Collection Interface)? - Why can't we create instance of Collections class (not Collection Interface)? 为什么接口方法在实现接口的类中不能是静态的? - Why interface methods can't be static in class that implements the interface? 如何在Java中使用Collections对从类填充的列表进行排序 - How to use Collections in java to sort list populated from a class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM