Java8中findAny和findFirst的區別


試驗了一下java stream中的findAny和findFirst,發現都返回了列表中的第一個元素。那么,這兩種方法的區別是什么呢?

查看了一下Java API document:

findFirst:

findFirst

Optional<T> findFirst()

Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. If the stream has no encounter order, then any element may be returned.

This is a short-circuiting terminal operation.

Returns:

an Optional describing the first element of this stream, or an empty Optional if the stream is empty

Throws:

NullPointerException - if the element selected is null

顧名思義,即返回列表中的第一個元素。

這里的short-circuiting是指:有時候需要在遍歷中途停止操作,比如查找第一個滿足條件的元素或者limit操作。在Stream中short-circuiting操作有:anyMatch、allMatch、noneMatch、findFirst、findAny、limit,這些操作在Sink中都有一個變量來判斷是否短路,比如limit用的是m,match用的是stop,find用的是hasValue。

這里的terminal operation是指:一個終結操作,比如foreach,IntStream.sum

那么,findAny是什么呢?

findAny

Optional<T> findAny()

Returns an Optional describing some element of the stream, or an empty Optional if 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.)

Returns:

an Optional describing some element of this stream, or an empty Optional if the stream is empty

Throws:

NullPointerException - if the element selected is null

See Also:

findFirst()

可以看到findAny()操作,返回的元素是不確定的,對於同一個列表多次調用findAny()有可能會返回不同的值。使用findAny()是為了更高效的性能。如果是數據較少,串行地情況下,一般會返回第一個結果,如果是並行的情況,那就不能確保是第一個。比如下面的例子會隨機地返回OptionalInt[50]。

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

讓我們來舉另外一個例子:

  1.  
    List<String> lst1 = Arrays.asList( "Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
  2.  
    List<String> lst2 = Arrays.asList( "Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
  3.  
     
  4.  
    Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith( "D")).findFirst();
  5.  
    Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith( "J")).findAny();
  6.  
     
  7.  
    System.out.println(findFirst.get()); //總是打印出David
  8.  
    System.out.println(fidnAny.get()); //會隨機地打印出Jack/Jill/Julia


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM