当我在观看 Streams 视频时,我发现自己对 Streams API 如何对循环方法的命令式方法进行惰性评估感到困惑。
这是典型的 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;
}
}
}
这里是预期的输出:
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
现在这里是使用 Streams API 的相同代码:
arr.stream()
.filter(Lazy::isGreater)
.filter(Lazy::isEven)
.map(Lazy::doubleIt)
.findFirst();
它也以同样的方式评估。那么 filter()
是如何提供我们使用传统 for 循环无法获得的不同内容的呢?
最佳答案
这里是关键:可组合性
arr.stream()
.filter(Lazy::isGreater)
.filter(Lazy::isEven)
.map(Lazy::doubleIt)
.findFirst();
这看起来无害,但现在这是一个值:
arr.stream()
.filter(Lazy::isGreater)
您可以将它交给一个方法并在其上进行构建。
等效的 for 循环可以做什么?您可以在任何使用它的地方复制粘贴它。它不是可组合的抽象。
此外,Stream 还使迭代和处理数据的方式变得抽象。它可以使用工作池,或者 fork join,或者它可以按照有利于 CPU 缓存局部性的顺序进行,或者任何数量的事情。您不再确切地告诉 JVM 如何做某事,而是更接近于告诉 JVM 做什么并让它弄清楚如何做。
关于Java 8 - 惰性评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33720757/