当我发现自己对Streams API如何对强制性for循环方法进行惰性评估感到困惑时,我正在观看Streams视频。
这是典型的for循环代码,该代码检查第一个大于3的数字,甚至是偶数,然后简单地将其打印并返回。
List<Integer> arr = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9);
for (int i : arr) {
System.out.println(" Checking if is Greater: " + i);
if (i > 3) {
System.out.println("checking if is Even " + i);
if (i % 2 == 0) {
System.out.println(i * 2);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里是预期的输出:
Checking if is Greater: 1
Checking if is Greater: 2
Checking if is Greater: 3
Checking if is Greater: 5
Checking if is Even 5
Checking if is Greater: 4
Checking if is Even 4
8
Run Code Online (Sandbox Code Playgroud)
现在,这里是使用Streams API的相同代码:
arr.stream()
.filter(Lazy::isGreater)
.filter(Lazy::isEven)
.map(Lazy::doubleIt)
.findFirst();
Run Code Online (Sandbox Code Playgroud)
它也以相同的方式进行评估。那么,如何filter()提供使用传统的for循环无法获得的不同之处呢?
关键是:可组合性
arr.stream()
.filter(Lazy::isGreater)
.filter(Lazy::isEven)
.map(Lazy::doubleIt)
.findFirst();
Run Code Online (Sandbox Code Playgroud)
这看起来无害,但现在这是一个值:
arr.stream()
.filter(Lazy::isGreater)
Run Code Online (Sandbox Code Playgroud)
您可以将其交给一个方法并在其基础上进行构建。
等效的 for 循环可以做什么?您可以将其复制粘贴到任何使用它的地方。它不是可组合的抽象。
此外,Stream还使得数据的迭代和处理方式变得抽象。它可以使用工作池,或 fork join,或者可以按照有利于 CPU 缓存局部性的顺序,或任何数量的东西。您不再确切地告诉 JVM 如何做某事,而是更接近于告诉它要做什么并让它弄清楚如何做。
| 归档时间: |
|
| 查看次数: |
2275 次 |
| 最近记录: |