考虑以下Scala代码:
var myStream = Stream(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
var cnt = 0;
def duplicate(in: Stream[Int]): Stream[Int] = {
in.flatMap(elem => {
cnt += 1
Stream(elem, elem)
})
}
myStream = duplicate(myStream)
myStream = duplicate(myStream)
myStream = duplicate(myStream)
myStream = duplicate(myStream)
"First elem: " + myStream.head
"cnt: " + cnt
"Size: " + myStream.size
"cnt: " + cnt
最后4行打印:
First elem: 1
cnt: 4
Size: 160
cnt: 150
这与预期完全一致。 要计算第一个元素,需要运行 flatMap 4次,因此在该步骤中cnt等于4。
现在考虑Java示例:
static int cnt = 0;
public static void main(String[] args) {
IntStream range = IntStream.range(1, 11);
range = duplicate(range);
range = duplicate(range);
range = duplicate(range);
range = duplicate(range);
System.out.println(
range.findAny()//range.findFirst()
);
System.out.println(cnt);
//System.out.println(
// range.count()
//);
//System.out.println(cnt);
}
private static IntStream duplicate(IntStream elem) {
return elem.flatMap(e -> {
++cnt;
return IntStream.of(e, e);
});
}
Java示例需要运行两次,因为find是终端操作。 所以经过两次运行:
first element is: OptionalInt[1]
cnt: 15
Size: 160
cnt: 150
看起来喜欢蒸汽懒惰在Java中以某种方式被打破。 我不知道为什么Java需要15( cnt:15 ) flatMap 操作来计算结果。
对于小例子,这不是问题,但是对于更复杂的流程,当一个人只关心第一个流元素时,这可能会导致性能问题。