Java 8 - 惰性评估?

标签 java java-8

当我在观看 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/

相关文章:

java - 在 Java 中 : why some Stream methods take int instead of byte or even char?

java - 我可以将哪种类型的参数传递到 JAVA 8 中的 ToIntFunction 功能接口(interface)中

java - 在命令行中使用斯坦福 CoreNLP 时出错

Java 使用 do-while 和 for-loop 创建解决用户输入错误的新方法

java - 是什么决定了 Kafka 消费者偏移量?

java - 读取 JSON 到对象 : java. lang.OutOfMemoryError: Java 堆空间

java - 具有相同方法的多个 Java 8 枚举

java - 检查数组中最大和最小元素的数量

java - 使用通配符类型减少流

java - Collectors::toList 循环推理