Java 8-惰性评估?

Age*_*ntX 6 java java-8

当我发现自己对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循环无法获得的不同之处呢?

Ala*_*Dea 4

关键是:可组合性

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 如何做某事,而是更接近于告诉它要做什么并让它弄清楚如何做。

  • @AgentX 惰性评估是锅炉房的东西。它是根据功能来销售,而不是根据从业者可以自由做的事情来销售。我们不应该卖火花,而应该专注于卖马里奥投掷火球的能力。很容易忘记;) (4认同)