Stream API支持惰性操作,所以我理解它是垂直计算的。
但是,根据极限方法的位置不同,结果也不同。为什么在过滤后使用 limit 后,得到有限数量的结果后仍继续操作?
// code 1
int sum = IntStream.range(1, 101)
.map(i -> {
System.out.format("map : %d \n",i);
return i * i;
})
.limit(5)
.filter(i -> {
System.out.format("filter : %d\n",i);
return i<20;
})
.sum();
System.out.println(sum);
// result
map : 1
filter : 1
map : 2
filter : 4
map : 3
filter : 9
map : 4
filter : 16
map : 5
filter : 25
30
// code 2
int sum = IntStream.range(1, 101)
.map(i -> {
System.out.format("map : %d \n",i);
return i * i;
})
.filter(i -> {
System.out.format("filter : %d\n",i);
return i<20;
})
.limit(5)
.sum();
System.out.println(sum);
// result
map : 1
filter : 1
map : 2
filter : 4
...
map : 97
filter : 9409
map : 98
filter : 9604
map : 99
filter : 9801
map : 100
filter : 10000
30
我以为这两个结果会相似,但我想知道为什么操作次数有差异。
在第一种情况下,它按预期工作,将限制保持为 5 并打印出 after 限制语句。
在第二种情况下,直到应用继续过滤打印 before 限制的过滤器语句之后才会检查限制。 它仍然有限制,但过滤器也在发挥作用。 限制是从过滤器中“扔掉”多余的部分。
如果您在第二个版本的限制之后放置
peek
语句,并删除过滤器打印语句,则只会打印 5 个。