在Java 8中,我使用Streams打印输出,但是大小即将为0。为什么?
public class IntermediateryAndFinal {
public static void main(String[] args) {
Stream<String> stream = Stream.of("one", "two", "three", "four", "five");
Predicate<String> p1 = Predicate.isEqual("two");
Predicate<String> p2 = Predicate.isEqual("three");
List<String> list = new ArrayList<>();
stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(list::add);
System.out.println("Size = "+list.size());
}
}
答案 0 :(得分:4)
理想情况下,您不应更改外部列表,而可以使用Collectors.toList()
将其收集到列表中:
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.collect(Collectors.toList()); // triggers the evaluation of the stream
System.out.println("Size = "+list.size());
在您的示例中,仅在像
这样的终端操作时评估流allMatch()
anyMatch()
noneMatch()
collect()
count()
forEach()
min()
max()
reduce()
遇到。
答案 1 :(得分:2)
由于您尚未完成流操作,即peek
是中间操作。您必须使用 终端操作 才能继续执行。
建议:而是使用终端操作(例如collect
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.collect(Collectors.toList());
此外:对于以下代码,添加peek
后的filter
来观察值可能会有些棘手
List<String> list = stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(System.out::println) // addition
.collect(Collectors.toList());
输出看起来像:
one two two // filtered in three three // filtered in four five
答案 2 :(得分:1)
流很懒。您桅杆呼叫终端操作,例如forEach
:
stream.peek(System.out::println)
.filter(p1.or(p2))
.forEach(list::add);
如果要使用peek
作为调试的中间操作,则必须随后调用终端操作:
stream.peek(System.out::println)
.filter(p1.or(p2))
.peek(list::add);
.<any terminal operation here>();
顺便说一句,如果您只想将所有过滤后的值存储在列表中,那么最好使用collect(toList())
。
答案 3 :(得分:0)
您对filter
和peek
所做的所有工作都建立了一系列应用于该流的操作。您实际上尚未使其中任何一个运行。您必须添加一个终端操作,例如count
。 (另一个答案建议使用forEach
添加到列表中,但我认为您正在专门尝试使用中间操作peek
。)