IT TIP

Java 8에서 findAny ()와 findFirst ()의 차이점

itqueen 2020. 11. 21. 08:30
반응형

Java 8에서 findAny ()와 findFirst ()의 차이점


Java 8 API Stream#findAny()API 사이에 약간의 혼란이 있습니다.Stream#findFirst()Stream

예를 들어 필터와 함께 사용할 때 둘 다 스트림에서 첫 번째로 일치하는 요소를 반환한다는 것을 이해했습니다.

그렇다면 동일한 작업에 대해 두 가지 방법이있는 이유는 무엇입니까? 내가 뭔가를 놓치고 있습니까?


예를 들어 필터와 함께 사용할 때 둘 다 스트림에서 첫 번째로 일치하는 요소를 반환한다는 것을 이해했습니다.

그건 사실이 아니야. javadoc가에 따르면 Stream#findAny():

스트림의 일부 요소를 Optional<T>설명 하거나 스트림이 비어 있는 경우 비어 있는 것을 리턴합니다 . 이 작업의 동작은 명시 적으로 비 결정적입니다. 스트림의 모든 요소를 ​​자유롭게 선택할 수 있습니다. 이는 병렬 작업에서 최대 성능을 허용하기위한 것입니다.Optional<T>

while Stream.findFirst()스트림의 첫 번째 요소 Optional<T>엄격하게 설명 하는 것을 반환 합니다. Stream클래스는없는 .findOne()난 당신이 의미 가정, 그래서 방법을 .findFirst().


아니요, 둘 다 Stream의 첫 번째 요소를 반환하지 않습니다.

출처 Stream.findAny()(강조 내) :

스트림의 일부 요소Optional설명 하거나 스트림이 비어 있는 경우 비어 있는 것을 리턴합니다 .Optional

이것은 단락 터미널 작동입니다.

이 작업의 동작은 명시 적으로 비 결정적입니다. 스트림의 모든 요소를 ​​자유롭게 선택할 수 있습니다. 이는 병렬 작업에서 최대 성능을 허용하기위한 것입니다. 비용은 동일한 소스에서 여러 호출이 동일한 결과를 반환하지 않을 수 있다는 것입니다. (안정된 결과를 원하면 findFirst()대신 사용하십시오.)

따라서 더 간단하게 말하면 Stream의 첫 번째 요소를 선택할 수도 있고 선택하지 않을 수도 있습니다.

현재 Oracle 특정 구현에서는 비 병렬 파이프 라인의 첫 번째 요소를 반환 할 것이라고 생각합니다. 그러나 병렬 파이프 라인에서는 항상 그렇지는 않습니다 (예를 들어 실행하면 실행 했을 때 System.out.println(IntStream.range(0, 100).parallel().findAny());반환 됨 OptionalInt[50]). 어쨌든 그것에 의존 해서는 안됩니다 .


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

병렬 모드에서는 findAny순서가 보장되지 않지만 그렇습니다 findFirst.

차이점을 보여주기 위해 코드 스 니펫을 작성 했습니다.


findFirst()그리고 findAny()사용하는 동안 조심하십시오 .

(그 자바 독부터 같이 여기여기 ) 두 방법 스트림에서 임의의 요소를 리턴 - 스트림은 가지고 있지 않는 상대 순서 케이스되는, findFirst()하면서 첫 번째 요소를 반환 findAny()모든 요소를 반환한다.

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());
    }

출력 :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().

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.

Detailed Article:


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.

Reference

Time 1:25:00

참고URL : https://stackoverflow.com/questions/35359112/difference-between-findany-and-findfirst-in-java-8

반응형