在Java8中,惰性评估和渴望评估是如何工作的

在Java8中,惰性评估和渴望评估是如何工作的,java,java-8,lazy-evaluation,Java,Java 8,Lazy Evaluation,我知道在对流调用terminal方法之前,流是惰性的。 我所知道的是,在终端方法被调用之后,所有的中间方法都会按照调用的顺序执行 但有了下面的程序,我无法了解流是如何工作的。这是代码,我已经试过了 import java.util.*; import java.util.stream.*; class TestEagerLazy { public static void main(String[] args) { ArrayList<Integer> a =

我知道在对流调用terminal方法之前,流是惰性的。 我所知道的是,在终端方法被调用之后,所有的中间方法都会按照调用的顺序执行

但有了下面的程序,我无法了解流是如何工作的。这是代码,我已经试过了

import java.util.*;
import java.util.stream.*;

class TestEagerLazy
{
    public static void main(String[] args) {
        ArrayList<Integer> a = new ArrayList<>();

        a.add(4);a.add(5);a.add(8);
        a.add(7);a.add(3);a.add(65);
        a.add(87);a.add(2);a.add(12);
        a.add(58);a.add(42);

        Stream<Integer> st = a.stream().filter(b->{System.out.println("Tested: " + b);return (b%2)==0;});

        Spliterator<Integer> it = st.spliterator();

        System.out.println("\n\nIterator Results:");
        while(it.tryAdvance((j)->System.out.println("iter: "+j)));


        System.out.println("Last Statement");


    }
}
但我得到的结果如下:

Iterator Results:
Tested: 4
Tested: 5
Tested: 8
Tested: 7
Tested: 3
Tested: 65
Tested: 87
Tested: 2
Tested: 12
Tested: 58
Tested: 42
iter: 4
iter: 8
iter: 2
iter: 12
iter: 58
iter: 42
Last Statement
Iterator Results:
Tested: 4
iter: 4
Tested: 5
Tested: 8
iter: 8
Tested: 7
Tested: 3
Tested: 65
Tested: 87
Tested: 2
iter: 2
Tested: 12
iter: 12
Tested: 58
iter: 58
Tested: 42
iter: 42
Last Statement

具体的程序流程是什么?程序如何从tryAdvance流到流上的过滤器,然后再返回。

无状态流被设计为处理可能无限量的元素。为了实现这一点,流不能尝试同时对所有元素上的每个操作求值

顺序流总是一次执行一个元素的管道。在下一个元素开始之前,每个元素都经过整个管道。这就是懒惰评估有效的原因。它允许流短路,例如使用或。如果在每个阶段同时处理所有元素,则流将无法处理无限的数据源,例如来自

代码的输出表明元素一次一个地通过管道:

Iterator Results:
Tested: 4   // starting 1st element
iter: 4     // ending 1st element
Tested: 5   // starting 2nd element (fails the filter)
Tested: 8   // starting 3rd element
iter: 8     // ending 3rd element
Tested: 7   // starting 4th element (fails the filter)
...
Last Statement

这些行为在。

中有更为普遍的解释。您认为这些行为是什么?您为什么这么认为?--关键是它“试图将流向前推进一个元素”,并对其执行给定的操作。一次一个元素!正如老话所说:懒惰追求。许多流操作(如筛选、映射或重复删除)都可以延迟实现,从而提供了优化的机会。例如,“查找具有三个连续元音的第一个
字符串
”不需要检查所有输入字符串。换句话说,直到需要时才调用
filter()。这就是“懒惰”的定义。(但也许他们应该称之为“拖延”?)@Andreas:我认为“拖延”并不合适,因为这意味着流实现会做其他事情(编写Stackoverflow贡献?),而不是开始工作…