[英]Java 8 Stream - Filter and foreach method not printing as expected
I am executing the following program: 我正在执行以下程序:
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return true;
})
.forEach(s -> System.out.println("forEach: " + s));
And the output I got is: 我得到的输出是:
filter: d2
forEach: d2
filter: a2
forEach: a2
filter: b1
forEach: b1
filter: b3
forEach: b3
filter: c
forEach: c
However, I was expecting the following output: 但是,我期待以下输出:
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
forEach: d2
forEach: a2
forEach: b1
forEach: b3
forEach: c
Meaning, first the filter
method loop should have executed completely and then the forEach
method loop should have started. 意思是,首先应该完全执行
filter
方法循环,然后才能启动forEach
方法循环。
Is there anything I am doing wrong? 有什么我做错了吗?
Your expectation is wrong. 你的期望是错误的。
When the terminal operation forEach
is executed, it consumes one element of the Stream
at a time. 当执行终端操作
forEach
,它一次消耗一个Stream
元素。 Each element it consumes has to pass all the intermediate operations of the Stream
, which causes filter
to be executed on the element just prior to forEach
being executed on same element (assuming the element passes the filter
). 每消耗元件具有传递的所有的中间操作
Stream
,这会导致filter
的元件上刚刚之前执行forEach
被同一元件上执行(假设元件经过filter
)。
In other words, filter
is lazily applied to each element just when the next operation in the Stream
pipeline requires its next element (in your case the next operation is forEach
). 换句话说,当
Stream
管道中的下一个操作需要其下一个元素时(在您的情况下,下一个操作是forEach
), filter
被懒惰地应用于每个元素。
This means that if your terminal operation would only require some of the Stream elements to be processed (for example, if you replaced forEach()
with findFirst()
), the filter()
operation would only be executed until the first element passes it (which in your example means the filter will be executed only for the first element). 这意味着如果你的终端操作只需要处理一些Stream元素(例如,如果你用
findFirst()
替换了forEach()
findFirst()
), filter()
操作只会在第一个元素传递之前执行(在您的示例中,这意味着仅针对第一个元素执行过滤器)。
The processing of a Stream will start with a terminal operation and consume one item after another. Stream的处理将从终端操作开始,并逐个使用一个项目。 The advantages are:
优点是:
The program has to calculate only relevant items - if for example only one item is needed, the filter
is only called once: 程序必须只计算相关项目 - 例如,如果只需要一个项目,则只调用一次
filter
:
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return true;
})
.findAny()
.ifPresent(s -> System.out.println("forEach: " + s));
Output: 输出:
filter: d2
forEach: d2
You can even create infinte Streams (which would not be possible otherwise): 您甚至可以创建infinte Streams(否则将无法实现):
IntStream.iterate(0, i -> i+1)
.filter(s -> {
System.out.println("filter: " + s);
return true;
})
.peek(i -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
})
.forEach(s -> System.out.println("forEach: " + s));
Output: 输出:
filter: 0
forEach: 0
filter: 1
forEach: 1
... (up to infinity)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.