【发布时间】:2016-05-06 06:36:28
【问题描述】:
我一直在尝试了解和展示 Java 流如何在底层实现一种循环融合,以便可以将多个操作融合到一次传递中。
这里的第一个例子:
Stream.of("The", "cat", "sat", "on", "the", "mat")
.filter(w -> {
System.out.println("Filtering: " + w);
return w.length() == 3;
})
.map(w -> {
System.out.println("Mapping: " + w);
return w.toUpperCase();
})
.forEach(w -> System.out.println("Printing: " + w));
具有以下输出(每个元素的单遍融合非常清晰):
Filtering: The
Mapping: The
Printing: THE
Filtering: cat
Mapping: cat
Printing: CAT
Filtering: sat
Mapping: sat
Printing: SAT
Filtering: on
Filtering: the
Mapping: the
Printing: THE
Filtering: mat
Mapping: mat
Printing: MAT
第二个例子是一样的,但是我在过滤器和映射之间使用了 sorted() 操作:
Stream.of("The", "cat", "sat", "on", "the", "mat")
.filter(w -> {
System.out.println("Filtering: " + w);
return w.length() == 3;
})
.sorted()
.map(w -> {
System.out.println("Mapping: " + w);
return w.toUpperCase();
})
.forEach(w -> System.out.println("Printing: " + w));
这有以下输出:
Filtering: The
Filtering: cat
Filtering: sat
Filtering: on
Filtering: the
Filtering: mat
Mapping: The
Printing: THE
Mapping: cat
Printing: CAT
Mapping: mat
Printing: MAT
Mapping: sat
Printing: SAT
Mapping: the
Printing: THE
所以我的问题在这里,通过调用 distinct,我是否正确地认为因为它是一个“有状态”的中间操作,它不允许在单次通过(所有操作)期间单独处理单个元素.此外,由于 sorted() 有状态操作需要处理整个输入流以产生结果,因此此处无法部署融合技术,这就是为什么首先发生所有过滤,然后将映射和打印操作融合在一起,排序后?如果我的任何假设不正确,请纠正我,并随时详细说明我已经说过的内容。
此外,它如何在后台决定是否可以将元素融合在一起成为一次传递,例如,当 distinct() 操作存在时,是否有一个标志可以关闭以阻止它发生就像 distinct() 不存在时一样?
最后一个查询是,虽然将操作融合到单次通过的好处有时是显而易见的,例如,当与短路结合使用时。将 filter-map-forEach 甚至 filter-map-sum 等操作融合在一起的主要好处是什么?
【问题讨论】:
-
您可以通过调试示例来简单地回答您的问题
-
我猜,每次你写“distinct”时,你的意思是“sorted”……
标签: java java-8 java-stream sorted stateful