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

Man*_*pal 67 java java-8 java-stream

我有点困惑之间Stream#findAny(),并Stream#findFirst()在的 Stream在Java API 8.

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

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

Kon*_*kov 74

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

这不是真的.据javadoc的,Stream#findAny():

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

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

  • @KorayTugay - 不,在过滤器之后,无论存在什么剩余元素,“findAny”都可以(某种程度上)随机返回其中的任何元素,特别是在并行流操作中 (2认同)

Tun*_*aki 38

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

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

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

这是一种短路终端操作.

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

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

使用当前的Oracle特定实现,我相信它将返回非并行管道中的第一个元素.但是,在并行管道中,它并不总是(例如System.out.println(IntStream.range(0, 100).parallel().findAny());,执行OptionalInt[50]时它会返回).无论如何,你不能依赖它.


Ami*_*mir 6

findFirst返回流的第一个元素,但是findAny可以自由选择流中的任何元素。

List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");

Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();

System.out.println(findFirst.get()); //Always print David
System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
Run Code Online (Sandbox Code Playgroud)


小智 5

在并行模式下,findAny不保证顺序,但findFirst可以。

我写了一些代码片段来显示差异,请访问它