Java流中的中间操作

时间:2019-02-04 04:52:48

标签: java collections java-8 java-stream

在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());
    }
}

4 个答案:

答案 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)

您对filterpeek所做的所有工作都建立了一系列应用于该流的操作。您实际上尚未使其中任何一个运行。您必须添加一个终端操作,例如count。 (另一个答案建议使用forEach添加到列表中,但我认为您正在专门尝试使用中间操作peek。)