堆栈使用 Java 8 集合流 API
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30387579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stack using the Java 8 collection streaming API
提问by jbx
I have a method which generates an object each time I execute it, and I need to reverse the order with which I am getting them. So I thought the natural way to do it would be a Stack, since it is LIFO.
我有一个方法,每次执行它时都会生成一个对象,我需要颠倒获取它们的顺序。所以我认为最自然的方法是 Stack,因为它是 LIFO。
However, the Java Stackdoes not seem to play well with the new Java 8 streaming API.
但是,Java Stack似乎不能很好地与新的 Java 8 流 API 配合使用。
If I do this:
如果我这样做:
Stack<String> stack = new Stack<String>();
stack.push("A");
stack.push("B");
stack.push("C");
List<String> list = stack.stream().collect(Collectors.toList());
System.out.println("Collected: " + list);
The output I get is:
我得到的输出是:
Collected: [A, B, C]
Why isn't it outputing them in the expected LIFO order to the stream? Is this the right way to flush out all the items from the stack to a list in the right (LIFO) order?
为什么不以预期的 LIFO 顺序将它们输出到流?这是将堆栈中的所有项目以正确的 (LIFO) 顺序刷新到列表的正确方法吗?
回答by Zelldon
As already mentioned in the comments, we have well tested Deque
interface which should be preferred.
正如评论中已经提到的,我们有经过良好测试的Deque
界面,应该是首选。
But I will you give the reason why Stack
shouldn't be used.
但我会告诉你为什么Stack
不应该使用的原因。
At first, the Java Doc. of the Stack says itself:
首先,Java Doc。堆栈的自述:
A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example:
Deque stack = new ArrayDeque();
Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用此类。例如:
Deque stack = new ArrayDeque();
See JavaDoc.
请参阅JavaDoc。
So what it is the problem with the Stack
class.
那么这个Stack
类有什么问题。
Like Martin Fowler already mentioned in his book Refactoring: Improving the Design of Existing Codeat the refactoring method Replace Inheritance with Delegation, a Stack shouldn't inherit from a Vector.
就像 Martin Fowler 在他的《重构:改进现有代码的设计》一书中提到 的重构方法用委托替换继承一样,堆栈不应该从向量继承。
One of the classic examples of inappropriate inheritance is making a stack a subclass of vector. Java 1.1 does this in its utilities (naughty boys!) [6, p. 288]
不恰当继承的典型例子之一是将堆栈作为向量的子类。Java 1.1 在它的实用程序中做到了这一点(顽皮的孩子们!)[6, p. [288]
Instead, they should have used delegation like in the picture below, which is also from the book.
相反,他们应该使用如下图所示的委托,这也是本书中的。
See also here: Replace Inheritance with Delegation
另请参见此处:将继承替换为委托
So but why is this a problem:
那么,为什么这是一个问题:
Because the Stack has only 5 Methods:
因为 Stack 只有 5 个方法:
- pop
- push
- isEmpty
- search
size
size()
andisEmpty()
are inherited from theVector
class and the other methods from theVector
are not used. But through the inheritance, other methods are forwarded to theStack
class which makes no sense.
And Fowler says to this problem:
福勒对这个问题说:
You can live with the situation and use convention to say that although it is a subclass, it's using only part of the superclass function. But that results in code that says one thing when your intention is something else—a confusion you should remove.
您可以接受这种情况并使用约定来说明尽管它是一个子类,但它仅使用了超类函数的一部分。但这会导致代码在你的意图是另一件事时说一件事——你应该消除这种混淆。
This hurts the Interface Segregation Principle
这损害了接口隔离原则
which says:
其中说:
CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.
不应强迫客户依赖他们不使用的接口。
You can check out the source codeof the Vectorand Stackclass
and you will see that the Stack class inherit the spliterator
method
and the VectorSpliterator
innerClass from the Vector
class.
可以查看Vector和Stack类的源码,会看到Stack类继承了类的spliterator
方法和VectorSpliterator
innerClass Vector
。
This method is used by the Collection
interface to impl. the default version of stream method:
Collection
接口使用该方法来实现。流方法的默认版本:
default Stream<E> More ...stream() {
return StreamSupport.stream(spliterator(), false);
}
So avoid simply the usage of the Vector
and Stack
class.
所以避免简单地使用Vector
andStack
类。
[6] Refactoring: Improving the Design of Existing Code Fowler, Martin year 1997
[6] 重构:改进现有代码 Fowler 的设计,Martin 1997 年