Java 8 Stream - 过滤和foreach方法不按预期打印

Kay*_*ayV 4 java java-8 java-stream

我正在执行以下程序:

Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
    System.out.println("filter: " + s);
    return true;
})
.forEach(s -> System.out.println("forEach: " + s));
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

filter:  d2
forEach: d2
filter:  a2
forEach: a2
filter:  b1
forEach: b1
filter:  b3
forEach: b3
filter:  c
forEach: c
Run Code Online (Sandbox Code Playgroud)

但是,我期待以下输出:

filter:  d2
filter:  a2
filter:  b1
filter:  b3
filter:  c 
forEach: d2
forEach: a2
forEach: b1
forEach: b3
forEach: c
Run Code Online (Sandbox Code Playgroud)

意思是,首先filter应该完全执行forEach方法循环,然后方法循环应该已经开始.

有什么我做错了吗?

Era*_*ran 9

你的期望是错误的.

当执行终端操作时forEach,它一次消耗一个元素Stream.它消耗的每个元素都必须传递它的所有中间操作Stream,这导致filter在元素forEach上执行之前就在元素上执行(假设元素通过了filter).

换句话说,filterStream管道中的下一个操作需要其下一个元素时(在您的情况下是下一个操作forEach),就会懒惰地应用于每个元素.

这意味着如果您的终端操作只需要处理一些Stream元素(例如,如果替换forEach()findFirst()),则filter()只会在第一个元素通过它之前执行操作(在您的示例中,这意味着过滤器将是仅针对第一个元素执行).