Stack using the Java 8 集合流 API

Stack using the Java 8 collection streaming API

我有一个每次执行都会生成一个对象的方法,我需要颠倒获取它们的顺序。所以我认为最自然的做法是堆叠,因为它是后进先出法。

但是,Java Stack 似乎不能很好地与新的 Java 8 流播放 API。

如果我这样做:

   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);

我得到的输出是:

Collected: [A, B, C]

为什么不按预期的后进先出顺序将它们输出到流中? 这是以正确的(后进先出)顺序将堆栈中的所有项目冲出到列表中的正确方法吗?

如评论中所述,我们已经很好地测试了Deque接口,应该是首选。

但是我会告诉你不应该使用 Stack 的原因。

首先,Java 文档。堆栈的自述:

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<Integer> stack = new ArrayDeque<Integer>();

参见 JavaDoc

所以 Stack class.

有什么问题

就像 Martin Fowler 在他的书中已经提到的 重构:改进现有代码的设计 在重构方法 Replace Inheritance with Delegation, Stack 不应继承自 Vector。

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]

相反,他们应该像下图那样使用委托, 也出自书本

另见此处:Replace Inheritance with Delegation

那么,为什么这是个问题:

因为Stack只有5个方法:

  1. 流行
  2. 推送
  3. 为空
  4. 搜索
  5. 尺寸

size()isEmpty()是继承自Vector class and the other methods from the Vector没有使用。但是通过继承,其他的方法都转发给了Stackclass,这就没有意义了。

福勒对这个问题说:

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.

这伤害了Interface Segregation Principle

上面写着:

CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.


你可以查看Vector and Stackclass的源代码 你会看到 Stack class 继承了 spliterator 方法 VectorSpliterator innerClass 来自 Vector class.

这个方法被Collection接口用来实现。流方法的默认版本:

default Stream<E> stream() {
  return StreamSupport.stream(spliterator(), false);
}

因此,请避免简单地使用 VectorStack class。

[6] 重构:改进现有代码的设计 Fowler,Martin 1997 年