Java流懒惰与融合与短路

时间:2016-02-02 10:00:50

标签: java java-8 lazy-evaluation java-stream fusion

我试图在Java流API中形成一个关于懒惰评估应用的cocise和一致的理解。

以下是我目前的理解:

  • 元素仅在需要时被消耗,即流是惰性的,并且中间操作是惰性的,例如,过滤器,只会在需要时进行过滤。
  • 中间操作可以融合在一起(如果它们是无状态的)。
  • 短路操作不需要处理整个流。

我想要做的就是把所有这些想法放在一起,确保我不会歪曲任何事情。我发现它很棘手,因为每当我阅读有关Java流的任何文献时,它都会说他们懒惰或利用懒惰的评估,然后非常可互换地开始谈论融合和短路等优化

我说下面的内容是对的吗?

  • fusion是如何在流API中实现延迟评估 - 即消耗元素,并且尽可能将操作融合在一起。我认为如果融合不存在那么我们肯定会回到急切的评估中,因为替代方案只是处理每个中间操作的所有元素,然后再转移到下一个中​​间操作?

  • 在没有融合或懒惰评估的情况下,短路是可能的,但通过这两个原则的实施,在流的背景下是非常有帮助的吗?

我对此有任何进一步的见解和清晰度表示感谢。

1 个答案:

答案 0 :(得分:38)

至于融合。让我们想象一下map操作:

.map(x -> x.squash())

Map

它是无状态的,它只是根据指定的算法(在我们的例子中压扁它们)转换任何输入。现在过滤操作:

.filter(x -> x.getColor() != YELLOW)

Filter

它也是无国籍的,它只是删除了一些元素(在我们的例子中是黄色元素)。现在让我们进行终端操作:

.forEach(System.out::println)

Display

它只显示终端的输入元素。融合意味着所有中间无状态操作都与终端消费者合并为单一操作:

.map(x -> x.squash())
.filter(x -> x.getColor() != YELLOW)
.forEach(System.out::println)

Fuse

整个管道融合为单个Consumer,它直接连接到源。处理每个元素时,源分裂器只执行组合的使用者,流管道不拦截任何内容并且不执行任何额外的簿记。这就是融合。 Fusion不依赖于短路。可以在没有融合的情况下实现流(执行一个操作,获取结果,执行下一个操作,在每个操作之后将控制权返回到流引擎)。它也可以融合而不会短路。