我正在执行以下程序:
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return true;
})
.forEach(s -> System.out.println("forEach: " + s));
我得到的输出是:
filter: d2
forEach: d2
filter: a2
forEach: a2
filter: b1
forEach: b1
filter: b3
forEach: b3
filter: c
forEach: c
但是,我期待以下输出:
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
forEach: d2
forEach: a2
forEach: b1
forEach: b3
forEach: c
意思是,首先应该完全执行 filter
方法循环,然后应该开始执行 forEach
方法循环。
我做错了什么吗?
最佳答案
你的期望是错误的。
当执行终端操作forEach
时,它一次消耗Stream
的一个元素。它消耗的每个元素都必须通过 Stream
的所有中间操作,这导致 filter
在 forEach
之前在元素上执行在同一元素上执行(假设该元素通过了 filter
)。
换句话说,filter
只是在 Stream
管道中的下一个操作需要其下一个元素时延迟应用于每个元素(在您的情况下,下一个操作是 forEach
).
这意味着如果您的终端操作只需要处理一些 Stream 元素(例如,如果您将 forEach()
替换为 findFirst()
) ,filter()
操作只会在第一个元素通过它之前执行(在您的示例中这意味着过滤器将仅针对第一个元素执行)。
关于Java 8 Stream - 过滤器和 foreach 方法未按预期打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40863739/