Java流操作调用

时间:2018-11-09 23:32:30

标签: java java-8 java-stream

任何人都可以指向官方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?

2 个答案:

答案 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)

来自the documentation

  

寻求懒惰。许多流操作(例如过滤,映射或重复删除)可以延迟实施,从而暴露出进行优化的机会。例如,“使用三个连续的元音查找第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生值或副作用)操作。中间操作总是很懒。

凭借这种优点,由于filter是一个中间操作,由于其惰性,它会在操作中创建一个新的Stream,因此它只会调用过滤谓词一次< / em>作为元素重新构建流的一部分。

您的方法可能在流中对其进行不同次数的调用的唯一方法是,如果在状态之间对流进行某种方式的突变,则这要考虑到流中实际上没有运行直到终端操作,实际上只能归因于上游的错误。