Java8流API和堆栈类
我想了解与Java8StreamsAPI一起使用时堆栈类的行为Java8流API和堆栈类,java,collections,stream,stack,Java,Collections,Stream,Stack,我想了解与Java8StreamsAPI一起使用时堆栈类的行为 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 + " ")); Stack s=新堆栈(); s、 推(1); s、 推(2); s、 推(3); s、 推(4); s、 stream().forEach
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 + " "));
Stack s=新堆栈();
s、 推(1);
s、 推(2);
s、 推(3);
s、 推(4);
s、 stream().forEach(x->System.out.print(x+);
根据堆栈类的约定,此代码应打印4 3 2 1
但是,它会打印1234
基本上我想了解:
误解:
stream()
方法来自收集接口
它的javadoc告诉我们:
返回以此集合作为其源的序列流
换句话说,“流契约”不知道也不关心“堆栈契约”
除此之外,“堆栈契约”是关于“堆栈操作”的。换句话说:当通过流迭代堆栈时,不能保证元素的顺序
Stack本身的javadoc告诉我们:
Stack类表示后进先出(LIFO)对象堆栈。它通过五个操作扩展了类Vector,允许将向量视为堆栈
因此,您就明白了:堆栈只不过是一个向量(列表),它提供了支持“堆栈行为”的附加操作。你可以在这里看到:
for (Integer i : s) {
System.out.println(i);
}
因此,即使“只是”迭代堆栈,忽略streamish部分,它也会按插入顺序1、2、3、4打印元素。堆栈类很旧(实际上早于集合API),您应该使用
Deque
。正如javadoc注释所示,Deques也可以用作后进先出(Last-In-First-Out)堆栈。此接口应优先于遗留类使用。像
因为
Stack extends Vector-保持原始插入顺序,pop将为您提供堆栈中的最后一个对象
,事实上,我认为在调用stream()时打破了直观的顺序。根据Stack类的约定,此代码应该打印4 3 2 1。。。除非堆栈为空,否则仅当您
pop
内容时。a)“堆栈类的契约”的哪一部分使您认为它应该打印4 3 2 1
?请从文件中引用。b) 文档清楚地说明了“Deque接口及其实现,应该优先于此类使用。”-为什么要使用过时的类?1)Stack
使用Vector
的迭代器,该迭代器基于光标,起始位置设置为0
。他们的Iterator#next
基本上返回elementData[cursor++]
,其中elementData
是两个类用来存储元素的普通Object[]
数组。2)实际上不是。API是清晰的,并且有很好的文档记录。(这些类已经过时了,没有人想使用/支持/改进它们[部分原因是你不能在不破坏某些东西的情况下进行太多的更改])3)可能你需要重写stream()
,spliterator()
(对于stream-API)和forEach()
,iterator()
(对于iterator-API)的行为回答不错。谢谢。这是一个很好的答案,没有回答OP的任何问题(有3个)@AndrewTobilko,在字里行间。它基本上说:“不要浪费时间使用堆栈,使用Deques”;-)
Deque<Integer> s = new ArrayDeque<>();
4 3 2 1
it prints 1 2 3 4.