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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35359112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:35:34  来源:igfitidea点击:

Difference between findAny() and findFirst() in Java 8

javajava-8java-stream

提问by Mandeep Rajpal

I am little confused between Stream#findAny()and Stream#findFirst()of the StreamAPI in Java 8.

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

What I understood is that both will return the first matched element from the stream, for example, when used in conjunction with filter?

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

So, why two methods for the same task? Am I missing something?

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

采纳答案by Konstantin Yovkov

What I understood is that both will return the first matched element from the stream, for example, when used in conjunction with filter?

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

That's not true. According to the javadoc, Stream#findAny():

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

Returns an Optional<T>describing someelement of the stream, or an empty Optional<T>if the stream is empty. The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream.This is to allow for maximal performance in parallel operations;

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

while Stream.findFirst()will return an Optional<T>describing strictlythe first element of the stream. The Streamclass doesn't have a .findOne()method, so I suppose you meant .findFirst().

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

回答by Tunaki

No, both will not return the first element of the Stream.

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

From Stream.findAny()(emphasis mine):

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

Returns an Optionaldescribing some elementof the stream, or an empty Optionalif the stream is empty.

This is a short-circuiting terminal operation.

The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations; the cost is that multiple invocations on the same source may not return the same result. (If a stable result is desired, use findFirst()instead.)

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

这是短路端子操作。

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

So to put it more simply, it may or may not choose the first element of the Stream.

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

With the current Oracle specific implementation, I believe that it will return the first element in non-parallel pipeline. However, in a parallel pipeline, it won't always (execute for example System.out.println(IntStream.range(0, 100).parallel().findAny());, it returned OptionalInt[50]when I ran it). Anyhow, you must notrely on that.

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

回答by jiahut

in parallel mode the findAnydoes not guaranteed order, but the findFirstdoes.

在并行模式下,findAny不保证顺序,但findFirst确实如此。

I wrote some code snippet to show the difference, visit it

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

回答by emon

In stream findFirst and findAny return first element and do not execute the rest but in parallelStream, it is not passible to say the order and parallelStream executes the rest of the collection.

在流 findFirst 和 findAny 中,返回第一个元素并且不执行其余部分,但在 parallelStream 中,说顺序是不可靠的,parallelStream 执行集合的其余部分。

Reference

参考

Time 1:25:00

时间 1:25:00

回答by Amir

findFirst return the first elements of the stream but findAny is free to select any element in the stream.

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

List<String> lst1 = Arrays.asList("Jhonny", "David", "Hyman", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Hyman", "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 Hyman/Jill/Julia :behavior of this operation is explicitly nondeterministic

回答by Vishwa Ratna

I will just say that beware Of findFirst()And findAny()while using.

我只会说在使用时要小心findFirst()findAny()

As from from their Javadoc (hereand here) both methods return an arbitrary element from the stream – unless the stream has an encounter order, in which case findFirst()returns the first element while findAny()will return any element.

从他们的 Javadoc(这里这里)开始,这两种方法都从流中返回一个任意元素——除非流有一个遇到顺序,在这种情况下findFirst()返回第一个元素而findAny()将返回任何元素。

Suppose we have custom listconsisting ISBN and BOOK name. For a scenario look at this example:

假设我们有自定义的listISBN 和 BOOK 名称。有关场景,请查看此示例:

public class Solution {
   private Integer ISBN;
   private String BookName;

public Solution(int i, String string) {
    ISBN =i;
    BookName = string;
}
//getters and setters
}


public static void main(String[] args) {
        List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action"));
 System.out.println(Library.stream()
        .map(p->p.getBookName())
        .sorted(Comparator.reverseOrder())
        .findFirst());
    }

Output: Optional[Java in Action]

输出Optional[Java in Action]

There can be scenarios when the Book name are same but ISBN numbers are different, in that case sorting and finding the book can be much similar to findAny()and will give wrong result. Think of a scenario where 5 books are named "Java Reference" but have different ISBN numbers and findFirst()book by name will result in same as findAny().

可能存在书籍名称相同但 ISBN 编号不同的情况,在这种情况下,排序和查找书籍可能非常相似,findAny()并且会给出错误的结果。想象一个场景,其中 5 本书被命名为“Java 参考”,但具有不同的 ISBN 号,并且findFirst()书名将导致与findAny().

Think of a scenario where:

考虑一个场景:

 ISBN    Name Of book
+-----+------------------+
| 100 | Java-8 in Action |
+-----+------------------+
| 101 | Java-8 in Action |
+-----+------------------+
| 102 | Java-8 in Action |
+-----+------------------+
| 103 | Java-8 in Action |
+-----+------------------+
| 104 | Java-8 in Action |
+-----+------------------+

here findFirst() and findAny() will give same result even if sorted on BookByName.

这里 findFirst() 和 findAny() 即使按BookByName排序也会给出相同的结果

Detailed Article:

详细文章: