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

2022-08-31 09:16:23

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

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

那么,为什么两种方法可以完成相同的任务呢?我错过了什么吗?


答案 1

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

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

返回描述流的某个元素,如果流为空,则返回空元素。此操作的行为是显式非确定性的;可以自由选择流中的任何元素。这是为了在并行操作中实现最佳性能;Optional<T>Optional<T>

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


答案 2

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

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

返回描述流的某个元素,如果流为空,则返回空元素。OptionalOptional

这是一个短路端子操作。

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

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

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

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

当我运行它时,它又回来了。无论如何,你绝不能依赖它。OptionalInt[50]


推荐