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


90

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

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

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

답변:


93

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

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

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

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


여전히 이해가 안되는데 a filter가 적용된 후에도 적용된 findAny필터와 일치하지 않는 요소를 포함하여 모든 요소를 ​​반환 할 수 있다는 것입니다.
Koray Tugay

@KorayTugay-아니요, 필터 이후에 남아있는 요소가 무엇이든간에 findAny, 특히 병렬 스트림 작업에서 (일종의) 임의의 요소를 반환 할 수 있습니다.
KrishPrabakar

46

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

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

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

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

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

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

현재 Oracle 특정 구현에서는 병렬이 아닌 파이프 라인의 첫 번째 요소를 반환 할 것이라고 믿습니다. 그러나 병렬 파이프 라인에서는 항상 그렇지는 않습니다.

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

OptionalInt[50]내가 그것을 실행했을 때 그것은 돌아왔다 . 어쨌든 그것에 의존 해서는 안됩니다 .


17

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

2

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

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


1

스트림에서 findFirst 및 findAny는 첫 번째 요소를 반환하고 나머지는 실행하지 않지만 parallelStream에서는 순서를 말할 수 없으며 parallelStream은 나머지 컬렉션을 실행합니다.

참고

시간 1:25:00


1

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]

책 이름은 같지만 ISBN 번호가 다른 경우가있을 수 있습니다.이 경우 책을 정렬하고 찾는 것이 매우 유사 할 수 있으며 findAny()잘못된 결과를 제공합니다. 5 권의 책이 "Java Reference"로 명명되었지만 ISBN 번호가 다르고 findFirst()이름별로 책이 findAny().

다음과 같은 시나리오를 생각해보십시오.

 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 |
+-----+------------------+

여기서 findFirst () 및 findAny ()는 BookByName 으로 정렬하더라도 동일한 결과를 제공 합니다.

자세한 기사 :


-1

주문 Stream이없는 시기 findFirst()findAny()동일합니다. 그러나 Stream주문 findAny()하면 더 좋을 것입니다.


이것은 올바르지 않습니다. 이러한 방법은 동작과 사용 사례가 완전히 다르기 때문에 "더 나은"방법은 아닙니다. 또한, Stream"질서" 라는 것은 무엇을 의미 합니까? 항상 정렬 Stream되지만 (병렬화되지 않을 때마다 동일한 순서로 주어진 작업이 실행 됨 ) 사용자가 정렬하지 않을 수 있습니다.
Jezor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.