任何人都可以指向官方Java文档,该文档描述了Stream将为每个元素调用每个“无干扰且无状态”中间操作的次数。
例如:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o) {
return true;
}
以上方法当前将调用check
方法4次。
在当前或将来的JDK版本中,check
方法是否可能比通过List或任何其他标准创建的流中元素的数量更多或更少的次数 Java API?
答案 0 :(得分:15)
这与流的源无关,而是在流实现本身中完成的终端操作和优化。例如:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
自Java-9起,map
将不会一次执行。
或者:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
可能根本不会执行,因为源是TreeSet
,而获取第一个元素是微不足道的,但是,是否在流API中实现,则是另一个问题。 / p>
所以真正的答案在这里-这取决于,但是我无法想象一个执行比源中元素数量更多的操作。
答案 1 :(得分:3)
寻求懒惰。许多流操作(例如过滤,映射或重复删除)可以延迟实施,从而暴露出进行优化的机会。例如,“使用三个连续的元音查找第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生值或副作用)操作。中间操作总是很懒。
凭借这种优点,由于filter
是一个中间操作,由于其惰性,它会在操作中创建一个新的Stream
,因此它只会调用过滤谓词一次< / em>作为元素重新构建流的一部分。
您的方法可能在流中对其进行不同次数的调用的唯一方法是,如果在状态之间对流进行某种方式的突变,则这要考虑到流中实际上没有运行直到终端操作,实际上只能归因于上游的错误。