Java 流操作调用

2022-09-04 02:20:38

任何人都可以指出官方的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;
} 

以上当前将调用方法 4 次。check

在当前或将来版本的 JDK 中,该方法的执行次数是否可能多于或少于从 List 或任何其他标准 Java API 创建的流中的元素数?check


答案 1

这与流的源无关,而是与流实现本身完成的终端操作和优化有关。例如:

Stream.of(1,2,3,4)
      .map(x -> x + 1)
      .count();

由于java-9,不会被执行一次。map

艺术

 someTreeSet.stream()
            .sorted()
            .findFirst();

sorted可能根本不会被执行,因为源代码是a并且获取第一个元素是微不足道的,但是如果这是否在流API中实现,则是另一个问题。TreeSet

所以真正的答案在这里 - 这是视情况而定的,但我无法想象一个操作会比源代码中的元素数量执行得更多。


答案 2

文档中

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

由于这是一个中间操作,它作为其操作的一部分创建新的操作,由于其懒惰性,它只会调用每个元素的筛选器谓词一次,作为其重建流的一部分。filterStream

您的方法在流中可能具有不同数量的调用的唯一方法是,如果流以某种方式在状态之间发生突变,鉴于流中没有任何东西在终端操作之前实际运行,由于上游的错误,实际上才有可能。


推荐