我试图对Java流API中的懒惰评估的应用形成一个完整的理解。
这是我目前的理解。
我想做的是把所有这些想法融合在一起,并确保我没有歪曲任何东西。我发现这很棘手,因为每当我读到任何关于Java流的文献时,它都会说它们是懒惰的或利用懒惰的评估,然后非常交替地开始谈论优化,如融合和短路。
那么我说以下的话对吗?
融合是在流API中实现懒惰评估的方式--即消耗一个元素,并尽可能将操作融合在一起。我在想,如果没有融合,那么我们肯定会回到急切的评估,因为另一种选择就是在进入下一个操作之前处理每个中间操作的所有元素?
如果没有融合或懒惰评估,短路是可能的,但在流的上下文中,这两个原则的实现非常有帮助。
我希望能进一步了解和澄清这个问题。
至于融合。让我们想象一下,这里有一个 map
操作。
.map(x -> x.squash())
它是无状态的,它只是根据指定的算法转换任何输入(在我们的例子中是压扁它们)。现在是过滤操作。
.filter(x -> x.getColor() != YELLOW)
它也是无状态的,它只是删除一些元素(在我们的例子中是黄色的)。现在我们来看看终端操作。
.forEach(System.out::println)
它只是将输入的元素显示在终端上。融合意味着所有中间的无状态操作与终端消费者操作合并为一个操作。
.map(x -> x.squash())
.filter(x -> x.getColor() != YELLOW)
.forEach(System.out::println)
整个管道被融合成一个 Consumer
其中直接连接到源。当每一个单元素处理完毕后,源头分割器只是执行合并后的消费者,流管道不拦截任何东西,也不进行任何额外的记账。这就是融合。融合不依赖于短路。可以实现流而不融合(执行一个操作,取结果,执行下一个操作,把每个操作后的控制权带回流引擎)。也可以在没有短路的情况下进行融合。