Java 8 中 findAny() 和 findFirst() 的区别

新手上路,请多包涵

我对 Stream#findAny()Stream#findFirst() Java 8 中的 Stream API 有点困惑。

我的理解是,两者都会从流中返回第一个匹配的元素,例如,当与过滤器一起使用时?

那么,为什么同一任务有两种方法呢?我错过了什么吗?

原文由 Mandeep Rajpal 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

我的理解是,两者都会从流中返回第一个匹配的元素,例如,当与过滤器一起使用时?

这不是真的。根据 javadoc, Stream#findAny()

返回一个 Optional<T> 描述流的 一些 元素,或者一个空的 Optional<T> 如果流是空的。此操作的行为显然是不确定的; 可以自由选择流中的任何元素。 这是为了在并行操作中实现最大性能;

Stream.findFirst() 将返回一个 Optional<T> 严格 描述流的第一个元素。 Stream 类没有 .findOne() 方法,所以我想你的意思是 .findFirst()

原文由 Konstantin Yovkov 发布,翻译遵循 CC BY-SA 3.0 许可协议

不,两者都 不会 返回 Stream 的第一个元素。

来自 Stream.findAny() (强调我的):

返回一个 Optional 描述流的 一些元素,或者一个空的 Optional 如果流是空的。

这是一个短路端子操作。

此操作的行为显然是不确定的; 可以自由选择流中的任何元素。这是为了在并行操作中实现最大性能;代价是对同一源的多次调用可能不会返回相同的结果。 (如果需要稳定的结果,请改用 findFirst() 。)

所以更简单地说,它可能会也可能不会选择 Stream 的第一个元素。

使用当前特定于 Oracle 的实现,我相信它将返回非并行管道中的第一个元素。但是,在并行管道中,它不会总是执行,例如

System.out.println(IntStream.range(0, 100).parallel().findAny());

当我运行它时,它返回了 OptionalInt[50] 。无论如何,你 不能 依赖那个。

原文由 Tunaki 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题