Java 8 Streams API和堆栈类

Ami*_*wal 3 java collections stack stream

我想了解与Java 8流API一起使用时Stack类的行为。

Stack<Integer> s = new Stack<>();

s.push(1);
s.push(2);
s.push(3);
s.push(4);

s.stream().forEach( x-> System.out.print(x + " "));
Run Code Online (Sandbox Code Playgroud)

根据Stack类的约定,此代码应为print 4 3 2 1

但是,它打印1 2 3 4

基本上我想了解:

  1. 导致此行为的底层底层实施细节。

  2. 使用Stream API迭代有序集合时,其他类似的陷阱也是如此。

  3. 如果我想实现自己的Stack类,该类可以与Java 8 Streams很好地配合使用,则需要进行哪些更改?

Gho*_*ica 5

误解:该stream()方法来自Collection接口。

它的javadoc告诉我们:

返回以此集合为源的顺序Stream。

换句话说:“ Stream Contract”不知道或不在乎“ Stack Contract”。

除此之外,“堆栈合同”与“堆栈操作”有关。换句话说:通过流迭代 Stack 时,不能保证元素的顺序。

而且,Stack本身的javadoc告诉我们:

Stack类表示对象的后进先出(LIFO)堆栈。它通过五个操作扩展了Vector类,这些操作允许将矢量视为堆栈。

因此,您就在那里:堆栈不过是向量(列表),它提供了启用“堆栈行为”的附加操作。您可以在这里看到:

for (Integer i : s) {
    System.out.println(i);
  }
Run Code Online (Sandbox Code Playgroud)

因此,即使“只是”迭代堆栈,而忽略了多余的部分,它也会按插入顺序1、2、3、4打印元素。


Ell*_*sch 5

Stack班是旧的(实际上早于集合API),你应该使用Deque。如Dequejavadoc所述,双端队列也可以用作LIFO(后进先出)堆栈。该接口应优先于旧Stack类使用。喜欢,

Deque<Integer> s = new ArrayDeque<>();
Run Code Online (Sandbox Code Playgroud)

将输出更改为

4 3 2 1 
Run Code Online (Sandbox Code Playgroud)