Java 8의 findAny()와 findFirst()의 차이점
나는 조금 혼란스럽다Stream#findAny()
그리고.Stream#findFirst()
의Stream
Java 8의 API
예를 들어 필터와 함께 사용할 경우 스트림에서 첫 번째 일치 요소가 반환되는 것으로 알고 있습니다.
그럼 왜 같은 작업에 두 가지 방법이 있을까요?내가 뭘 빼놓았나요?
예를 들어 필터와 함께 사용할 경우 스트림에서 첫 번째 일치 요소가 반환되는 것으로 알고 있습니다.
그렇지 않아요.javadoc에 따르면:
를 반환한다.
Optional<T>
스트림의 일부 요소 또는 빈 요소를 기술하는 경우Optional<T>
스트림이 비어 있는 경우.이 동작은 명시적으로 확정적이지 않습니다.스트림 내의 요소를 자유롭게 선택할 수 있습니다.이는 병렬 운영에서 최대의 성능을 제공하기 위한 것입니다.
이 반환되는 동안Optional<T>
흐름의 첫 번째 요소를 엄격하게 기술하고 있습니다.그Stream
클래스에는 이 없습니다..findOne()
방법, 그러니까 당신이 말한 것은.findFirst()
.
아니요, 둘 다 스트림의 첫 번째 요소를 반환하지 않습니다.
출처(강조 광산):
를 반환한다.
Optional
스트림의 일부 요소 또는 빈 요소를 기술하는 경우Optional
스트림이 비어 있는 경우.이것은 단락 단자 동작입니다.
이 동작은 명시적으로 확정적이지 않습니다.스트림 내의 요소를 자유롭게 선택할 수 있습니다.이는 병렬 동작에서 최대의 퍼포먼스를 실현하기 위한 것입니다.비용은 같은 소스로 여러 번 호출하면 같은 결과가 반환되지 않을 수 있습니다.(안정적인 결과가 필요한 경우 를 사용합니다.findFirst()
대신).
더 쉽게 말하면, 스트림의 첫 번째 요소를 선택할 수도 있고 선택하지 않을 수도 있습니다.
현재 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 및 findFirst에서는 첫 번째 요소를 반환하고 나머지는 실행하지 않지만 parallelStream에서는 순서를 말할 수 없으며 parallelStream은 나머지 컬렉션을 실행합니다.
시간 1:25:00
만 말할게findFirst()
★★★★★★★★★★★★★★★★★.findAny()
용용중 。
두 메서드는 Javadoc(여기 및 여기)에서와 마찬가지로 스트림에 조우 순서가 없는 한 스트림에서 임의의 요소를 반환합니다.findFirst()
는 첫 하고 첫 번째 요소는 반환됩니다.findAny()
는 임의의 요소를 반환합니다.
를 들어 관습이 가정해봅시다.list
ISBN 북시나리오에 대해서는, 다음의 예를 참조해 주세요.
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()
을 사용법이 「 Reference 붙여져 만, ISBN 과 ISBN 번호가 5권이라고 하는 를 해 주세요.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]스트림의 findAny와 findFirst를 테스트하기 위한 작은 코드를 개발했습니다.저는 1,000만 개의 더미 데이터를 만들고 그 데이터를 필터링하여 병렬 스트림과 순차 스트림을 사용하여 findAny와 findFirst를 적용합니다.
작은 실험을 통해 findAny와 findFirst가 동일한 결과를 제공하며 순차 스트림으로 첫 번째 결과를 제공한다는 것을 알게 되었습니다.그러나 findAny는 매번 parallelStream에서 동일한 결과를 생성하는 것을 보증하지 않으며 findFirst는 스트림이 병렬이든 순차적이든 항상 동일한 결과를 보증합니다.
public class TestFilter {
static class Employee {
String name;
double salary;
long id;
public Employee(String name, long id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
String genNextName() {
return "Emp-" + (this.id + 1);
}
double genNextSalary() {
return new Random().nextDouble() * 1000000;
}
long genNextId() {
return this.id + 1;
}
@Override
public String toString() {
return this.id + " " + this.name + " " + this.salary + "\n";
}
}
public static void main(String[] args) {
List<Employee> employees = createDummyEmployee(10000000l);
List<Employee> emps = null;
long time = 0;
for (int i = 0; i < 50; i++) {
Optional<Employee> e1 = employees.stream()
.filter(e -> e.name.endsWith("999"))
.filter(e -> e.salary > 10000)
.filter(e -> e.id % 2 == 1)
.findAny();
Optional<Employee> e2 = employees.stream()
.filter(e -> e.name.endsWith("999"))
.filter(e -> e.salary > 10000)
.filter(e -> e.id % 2 == 1)
.findFirst();
Optional<Employee> pe1 = employees.parallelStream()
.filter(e -> e.name.endsWith("999"))
.filter(e -> e.salary > 10000).filter(e -> e.id % 2 == 1)
.findAny();
Optional<Employee> pe2 = employees.parallelStream()
.filter(e -> e.name.endsWith("999"))
.filter(e -> e.salary > 10000)
.filter(e -> e.id % 2 == 1)
.findFirst();
System.out.print("FindAny without parallel : " + (e1.isPresent() ? e1.get().id +"": "null"));
System.out.print(" | FindFirst without parallel : " + (e2.isPresent() ? e2.get().id +"": "null"));
System.out.print(" | FindAny by Parallel : " + (pe1.isPresent() ? pe1.get().id +"": "null"));
System.out.print(" | FindFirst by Parallel : " + (pe2.isPresent() ? pe2.get().id +"": "null"));
System.out.println();
}
}
public static List<Employee> createDummyEmployee(long n) {
Employee e1 = new Employee("Emp-1", 1l, 1.0);
return Stream.iterate(e1, (Employee e) -> new Employee(e.genNextName(), e.genNextId(), e.genNextSalary()))
.limit(n).collect(Collectors.toList());
}
}
[실험 결과] [1] : https://i.stack.imgur.com/HOZjA.png
Stream
뒤바뀌다findFirst()
★★★★★★★★★★★★★★★★★」findAny()
똑같아요.하지만 언제Stream
findAny()
더 나아질 거야
언급URL : https://stackoverflow.com/questions/35359112/difference-between-findany-and-findfirst-in-java-8
'source' 카테고리의 다른 글
왜 java.lang이야?객체가 추상적이지 않습니까? (0) | 2023.01.09 |
---|---|
MySQL-python 설치 (0) | 2023.01.09 |
믹스인이란 무엇이며 왜 유용한가? (0) | 2023.01.09 |
Prepared Statement를 사용하여 삽입된 행의 ID를 반환하려면 어떻게 해야 합니까? (0) | 2023.01.09 |
chown: '/var/lib/mysql/' 소유권 변경: 작업이 허용되지 않습니다. (0) | 2023.01.09 |