[英]Why is there no “List.reverse()” method in Java?
In Java, to reverse elements in a List, I need to use:在 Java 中,要反转 List 中的元素,我需要使用:
Collections.reverse(list)
I was just wondering why Java doesn't implement the reverse method within the List
interface so that I could do the in-place reverse like this:我只是想知道为什么 Java 不在
List
接口中实现 reverse 方法,以便我可以像这样执行就地反向操作:
list.reverse()
Does anyone have any ideas about this?有没有人对此有任何想法?
Why is there no
List.reverse()
method in Java?为什么 Java 中没有
List.reverse()
方法?
Because there is a Collections.reverse(List)
method instead.因为有一个
Collections.reverse(List)
方法。
Because the API designers figured it was a bad idea to force every List
implementation 1 to implement a method that wasn't used 99.9% of the time 2 .因为 API 设计者认为强制每个
List
实现1实现一个在 99.9% 的时间都没有使用的方法2是一个坏主意。 This could be addressed by making the method "optional", but that has downsides too;这可以通过使方法“可选”来解决,但这也有缺点; eg runtime exceptions.
例如运行时异常。
Because for some kinds of list (stream wrappers / adapters for example) implementing in-place reverse would be problematic.因为对于某些类型的列表(例如流包装器/适配器),实现就地反向将是有问题的。 It changes the memory usage characteristics of the list by requiring it to be reified.
它通过要求将列表具体化来更改列表的内存使用特性。
Also note that the generic implementation ( source code ) of reverse()
that is provided by Collection
uses set
to swap elements.另请注意,
Collection
提供的reverse()
的通用实现( 源代码)使用set
来交换元素。 It is close to optimal for the standard list types.它接近于标准列表类型的最佳选择。
@shmosel comments: @shmosel 评论:
I assume OP is asking why it wasn't added as a default method, as List.sort() was.
我假设 OP 是在问为什么它没有像 List.sort() 那样作为默认方法添加。
Good point.好点。 Possibly the 99.9% argument applies.
可能 99.9% 的论点适用。 Bear in mind that this would only help people with a codebase that is built using a Java 8 or later compilers, etc.
请记住,这只会帮助那些使用 Java 8 或更高版本编译器等构建的代码库的人。
1 - This includes implementations in your codebase and 3rd-party libraries. 1 - 这包括您的代码库和第 3 方库中的实现。
2 - 86% of statistics are made up for theatrical effect :-) 2 - 86% 的统计数据用于戏剧效果:-)
For the same reason that fill
and rotate
and shuffle
and swap
and infinitely more possible list functions aren't declared in the List
interface.出于同样的原因,
List
接口中没有声明fill
和rotate
、 shuffle
和swap
以及无限更多可能的列表函数。 They're not part of the "list" abstraction;他们不是在“名单”抽象的一部分; rather, they can be implemented on top of that abstraction.
相反,它们可以在该抽象之上实现。
Once a List
implements the methods already in the List
interface, a reverse
function can be written on top of the List
abstraction without any knowledge of a particular List
implementation.一旦
List
实现了List
接口中已有的方法,就可以在List
抽象之上编写一个reverse
函数,而无需任何特定List
实现的知识。 Therefore, it would be pointless to force every class implementing List
to provide a custom implementation of reverse
(and fill
, rotate
, shuffle
, swap
, etc.).因此,强制每个实现
List
类都提供reverse
的自定义实现(以及fill
、 rotate
、 shuffle
、 swap
等)是没有意义的。
Because Collection
is an utilitarian class, that actually based on one of SOLID principle :因为
Collection
是一个实用类,它实际上基于SOLID原则之一:
S - Single Responsibility Principle S - 单一职责原则
This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes.
这个原则指出,如果我们有两个理由改变一个类,我们必须将功能拆分为两个类。
You have a class that play a some role, and if you need to manipulate of inner data you need to create some subsidiary class, that will plays another role.你有一个扮演某种角色的类,如果你需要操作内部数据,你需要创建一些子类,这将扮演另一个角色。
If you need list.reverse()
you need to use Eclipse Collections , when you can use just list.reverseThis()
, see this .如果您需要
list.reverse()
,则需要使用Eclipse Collections ,当您可以仅使用list.reverseThis()
,请参阅此。 In JDK list, a lot of method (like sort, max, min) does not be added.在 JDK 列表中,很多方法(如 sort、max、min)没有被添加。
It's two different ways of API design:这是两种不同的 API 设计方式:
Note: This question is a very specific case of "Why does the Collections class contain standalone (static) methods, instead of them being added to the List interface?"注意:这个问题是“为什么 Collections 类包含独立(静态)方法,而不是将它们添加到 List 接口中?”的一个非常具体的案例。 - one could even consider is as a duplicate.
- 甚至可以认为是重复。 Beyond that, arguing about the reasoning behind the decision for each individual method is reading tea leaves, and nobody can tell " the reason" for the design decision for the particular case of the
reverse
method (until, maybe Josh Bloch posts an answer here).除此之外,争论为每个方法的决定背后的推理是阅读茶叶,没有人可以告诉了针对的具体情况设计决定“的原因,”
reverse
法(直到,也许乔希布洛赫帖子这里的答案) . Interestingly, this is a point that is not covered in the Java Collections API Design FAQ ...有趣的是, Java 集合 API 设计常见问题解答中没有涵盖这一点......
Some of the other answers seem convincing at the first glance, but raise other questions.其他一些答案乍一看似乎令人信服,但引发了其他问题。 Particularly, some of them don't give a reason for the design decision at all.
特别是,其中一些根本没有给出设计决策的理由。 Even if there are other ways to emulate the behavior of a certain method, or when a method is not used "99.9% of all time", it can still make sense to include it in the interface.
即使有其他方法可以模拟某个方法的行为,或者当“99.9% 的时间”都没有使用某个方法时,将它包含在界面中仍然有意义。
Looking at the List
interface, you will notice that you can basically implement all methods based on two others:查看
List
接口,您会注意到您基本上可以基于另外两个方法来实现所有方法:
T get(int index)
int size()
(For a mutable list, you also need set
). (对于可变列表,您还需要
set
)。 These are exactly the ones that are still abstract in AbstractList
.这些正是
AbstractList
中仍然抽象的那些。 So all other methods are rather "convenience" methods that can be implemented canonically, based on these two methods.所以所有其他方法都是相当“方便”的方法,可以基于这两种方法规范地实现。 In this regard, I think that the answer Sam Estep contains an important point: One could argue to implement dozens of other methods.
在这方面,我认为Sam Estep 的答案包含一个重要的观点:人们可以争论实施其他数十种方法。 And there would certainly be good reasons to do so.
这样做肯定有充分的理由。 Having a look at the actual implementation of
Collections#reverse(List)
:看看
Collections#reverse(List)
的实际实现:
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
What is this REVERSE_THRESHOLD
and RandomAccess
thing there?那里的
REVERSE_THRESHOLD
和RandomAccess
是什么东西? Seriously, if I felt the necessity to introduce a tagging interface like RandomAccess
, I would strongly question my design.说真的,如果我觉得有必要引入像
RandomAccess
这样的标记界面,我会强烈质疑我的设计。 Whenever you have a method like每当你有一个像
void doSomethingWith(Type x) {
if (x instanceof Special) doSomethingSpecial((Special)x);
else doSomethingNormal(x);
}
then this is a strong sign that this should actually be a polymorphic method, which should be implemented accordingly for the Special
type.那么这是一个强烈的迹象,表明这实际上应该是一个多态方法,应该为
Special
类型相应地实现。
So yes, it have been justified to pull the reverse
method into the interface, to allow a polymorphic implementation.所以是的,将
reverse
方法拉入接口中是合理的,以允许多态实现。 The same applies to fill
rotate
, shuffle
, swap
, sort
and others.这同样适用于
fill
rotate
、 shuffle
、 swap
、 sort
等。 Similarly, one could have introduced a static method like同样,可以引入一个静态方法,如
Collections.containsAll(containing, others);
that offers what is now done with the Collection#containsAll
method.它提供了现在使用
Collection#containsAll
方法所做的事情。 But in general: The designers chose a particular set of methods that they found suitable.但总的来说:设计师选择了一组他们认为合适的特定方法。 One of the reasonings behind leaving out certain methods may be given by one of the bottom lines of the talk about "How to Design a Good API & Why it Matters" by Joshua Bloch , one of the core designers of the Java Collections API:
Java Collections API 的核心设计者之一Joshua Bloch 在关于“如何设计一个好的 API 以及为什么它很重要”的演讲中提到了忽略某些方法的原因之一:
Interestingly, of all the methods for which a polymorphic implementation (via a method in the List
interface) could have been reasonable, one actually found its way into the interface, using a Java 8 default
method: List#sort()
.有趣的是,在所有多态实现(通过
List
接口中的方法)可能是合理的方法中,有一个实际上找到了进入接口的方法,使用 Java 8 default
方法: List#sort()
。 Maybe others, like reverse
, will be added later...也许其他人,如
reverse
,将在以后添加......
Reverse is defined in Collections (with an extra (s)).反向在集合中定义(带有额外的 (s))。 This is not a part of collection hierarchy, rather it has been given as a part of utility class which can be used for different Lists.
这不是集合层次结构的一部分,而是作为可用于不同列表的实用程序类的一部分。
Reversing a list is not a key part of defining a list , so its kept out of interface and given separately.反转列表不是定义列表的关键部分,因此它被排除在接口之外并单独给出。 If defined in the interface, everyone will have to implement it, which may not be suitable for all.
如果在接口中定义,每个人都必须实现它,这可能不适合所有人。
The makers of collection could have build this in List hierarchy as well, ( Since most list derivations have an abstract class in between, they could have put it in any abstract class in between).集合的创建者也可以在 List 层次结构中构建它,(由于大多数列表派生之间都有一个抽象类,他们可以将它放在中间的任何抽象类中)。 However, to simplify everyone's life it makes sense to keep it in single utility class so that we don't have to figure out which class to look for all collection related utility functions.
然而,为了简化每个人的生活,将它保存在单个实用程序类中是有意义的,这样我们就不必弄清楚要查找所有与集合相关的实用程序函数的类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.