Avi*_*Avi 5 java filter java-8 java-stream
我最近Stream在Java 8 中学到了s并看到了这个例子:
IntStream stream = IntStream.range(1, 20);
Run Code Online (Sandbox Code Playgroud)
现在,让我们说我们想找到第一个可分为3和5的数字.我们可能filter两次,findFirst如下:
OptionalInt result = stream.filter(x -> x % 3 == 0)
.filter(x -> x % 5 == 0)
.findFirst();
Run Code Online (Sandbox Code Playgroud)
这听起来很合理.当我尝试这样做时出现了令人惊讶的部分:
OptionalInt result = stream.filter(x -> {System.out.println(x); return x % 3 == 0;})
.filter(x -> {System.out.println(x); return x % 5 == 0;})
.findFirst();
System.out.println(result.getAsInt());
Run Code Online (Sandbox Code Playgroud)
我希望得到类似的东西:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20然后:3 6 9 12 15 18.因为我们首先遍历1到20之间的所有数字,只过滤那些可被3除的那些数,然后迭代这个新的Stream并找到可被5除的那些数.
但相反,我得到了这个输出: 1 2 3 3 4 5 6 6 7 8 9 9 10 11 12 12 13 14 15 15 15
看起来它并没有超过所有数字.此外,它看起来x % 5 == 0只检查那些可被3除的数字.
我不明白为什么不迭代所有的数字.
这是代码的在线片段:http://www.tryjava8.com/app/snippets/5454a7f2e4b070922a64002b
嗯,关于流的理解是,与列表不同,它们不一定(必然)保存所有项目,而是一次计算每个项目(懒惰评估).
这意味着当你这样IntStream stream = IntStream.range(1, 20);做时,你并没有真正创建一个包含20个项目的集合.您创建了一个动态计算的集合.每次调用此流next都将计算下一个项目.其余的项目仍然"不存在"(有点说).
过滤器也是如此.
当您添加检查除以3的过滤器时,您将获得一个由2个计算组合的新流 - 第一个返回1中的数字直到达到20,第二个计算返回除以3的数字.重要的是要了解每次只计算第一项.这就是为什么当你将除以5的检查添加到它时,它只能处理那些可被3整除的项目.同样是为什么打印在15处停止.该findFirst方法返回通过所有3次计算的第一个数字(1-20)范围计算,由3计算除以5除法计算).
| 归档时间: |
|
| 查看次数: |
1369 次 |
| 最近记录: |