Java 8 의 API Stream#findAny()
와 API 간에 약간 혼동이 있습니다.Stream#findFirst()
Stream
예를 들어 필터와 함께 사용할 때 둘 다 스트림에서 첫 번째로 일치하는 요소를 반환한다는 것을 이해했습니다.
그렇다면 동일한 작업에 대해 두 가지 방법이있는 이유는 무엇입니까? 내가 뭔가를 놓치고 있습니까?
답변:
예를 들어 필터와 함께 사용할 때 둘 다 스트림에서 첫 번째로 일치하는 요소를 반환한다는 것을 이해했습니다.
그건 사실이 아니야. javadoc가에 따르면 Stream#findAny()
:
스트림의 일부 요소를
Optional<T>
설명 하거나 스트림이 비어 있는 경우 비어 있는 것을 리턴합니다 . 이 작업의 동작은 명시 적으로 비 결정적입니다. 스트림의 모든 요소를 자유롭게 선택할 수 있습니다. 이는 병렬 작업에서 최대 성능을 허용하기위한 것입니다.Optional<T>
while Stream.findFirst()
은 스트림의 첫 번째 요소 Optional<T>
를 엄격하게 설명 하는 것을 반환 합니다. Stream
클래스는없는 .findOne()
난 당신이 의미 가정, 그래서 방법을 .findFirst()
.
findAny
, 특히 병렬 스트림 작업에서 (일종의) 임의의 요소를 반환 할 수 있습니다.
아니요, 둘 다 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
findFirst()
그리고 findAny()
사용하는 동안 조심하십시오 .
(그 자바 독부터 같이 여기 및 여기 ) 두 방법 스트림에서 임의의 요소를 리턴 - 스트림은 가지고 있지 않는 상대 순서 케이스되는, findFirst()
하면서 첫 번째 요소를 반환 findAny()
모든 요소를 반환한다.
list
ISBN과 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 으로 정렬하더라도 동일한 결과를 제공 합니다.
filter
가 적용된 후에도 적용된findAny
필터와 일치하지 않는 요소를 포함하여 모든 요소를 반환 할 수 있다는 것입니다.