JAVA/Stream
[Java] Stream > findAny, findFirst
앵낄낄
2023. 7. 4. 19:24
반응형
git
https://github.com/ymwoo88/stream/tree/feature/find%EA%B8%B0%EB%8A%A5-%EC%98%88%EC%A0%9C
설명
findFirst
- Stream 안의 첫번째 데이터를 반환합니다.
- Stream이 비어있다면 빈 Optional을 반환합니다.
이 스트림의 첫 번째 요소를 설명하는 옵션을 반환하거나 스트림이 비어 있으면 빈 옵션을 반환합니다.
스트림에 발생 순서가 없으면 모든 요소가 반환될 수 있습니다.
이것은 단락 단자 작동입니다.
Returns: 이 스트림의 첫 번째 요소를 설명하는 Optional 또는 스트림이 비어 있는 경우 빈 Optional
Throws: NullPointerException – 선택한 요소가 null인 경우
Optional<T> findFirst();
findAny
- Stream 안의 아무 데이터나 리턴합니다.(매번 달라지기 때문에 순서가 필요 없을 때 사용합니다.
- Parallel Stream을 사용할 때 최적화를 할 수 있습니다.
- Stream이 비어있다면 빈 Optional을 반환합니다.
스트림의 일부 요소를 설명하는 옵션을 반환하거나 스트림이 비어 있으면 빈 옵션을 반환합니다.
이것은 단락 단자 작동입니다.
이 작업의 동작은 명시적으로 비결정적입니다.
스트림의 모든 요소를 자유롭게 선택할 수 있습니다. 이는 병렬 작업에서 최대 성능을 허용하기 위한 것입니다.
비용은 동일한 소스에 대한 여러 호출이 동일한 결과를 반환하지 않을 수 있다는 것입니다.
(안정적인 결과를 원하면 대신 findFirst()를 사용하십시오.)
Returns: 이 스트림의 일부 요소를 설명하는 Optional 또는 스트림이 비어 있는 경우 빈 Optional
Throws: NullPointerException – 선택한 요소가 null인 경우
See Also : findFirst()
Optional<T> findAny();
예제
- 샘플 데이터
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
private Long id;
private String name;
private String email;
private Integer age;
private Boolean isWorking;
private List<String> hobbies;
public static User getUserAmil() {
return User.builder()
.id(1L)
.name("amil")
.email("amil@ymwoo.com")
.age(28)
.isWorking(true)
.hobbies(List.of("골프", "영화감상"))
.build();
}
public static User getUserBenny() {
return User.builder()
.id(2L)
.name("benny")
.email("benny@ymwoo.com")
.age(26)
.isWorking(true)
.hobbies(List.of("골프", "낚시"))
.build();
}
public static User getUserCho() {
return User.builder()
.id(3L)
.name("cho")
.email("cho@ymwoo.com")
.age(33)
.isWorking(false)
.hobbies(List.of("등산", "캥핌"))
.build();
}
public static List<User> getExamUserList() {
return Arrays.asList(getUserAmil(), getUserCho(), getUserBenny());
}
@Override
public boolean equals(Object o) {
if (o instanceof User) {
return this.isWorking.equals(((User) o).getIsWorking()); // 값 비교
}
return false;
}
@Override
public int hashCode() {
return isWorking.hashCode();
}
}
- 예졔1) Stream findAny, findFirst
@Test
@DisplayName("Stream findAny, findFirst 테스트")
void case1() {
List<User> examUserList = User.getExamUserList();
Optional<User> first = examUserList.stream()
.filter(User::getIsWorking)
.findFirst(); // return 이 Optional
List<User> isWorkingUserList = examUserList.stream()
.filter(User::getIsWorking).toList();
// 2개 이상 검증
Assertions.assertEquals(2, isWorkingUserList.size());
// 2개 중에 any 뭐가 나올까..?
Optional<User> any = isWorkingUserList.stream()
.filter(User::getIsWorking)
.findAny(); // return 이 Optional
// 확인
log.info("findFirst = {}", first.get());
// any 결과를 보니까 first와 다를게 없어보이네.. 무조건 앞에께 튀나오네
log.info("findAny = {}", any.get());
}
19:08:49.333 [Test worker] INFO com.ymwoo.stream.first.StreamFirstSeriesTest -- findFirst = User(id=1, name=amil, email=amil@ymwoo.com, age=28, isWorking=true, hobbies=[골프, 영화감상])
19:08:49.341 [Test worker] INFO com.ymwoo.stream.first.StreamFirstSeriesTest -- findAny = User(id=1, name=amil, email=amil@ymwoo.com, age=28, isWorking=true, hobbies=[골프, 영화감상])
근데..
findAny의 경우 동일한 소스에 대한 여러 호출이 동일한 결과를 반환하지 않을 수 있다고하는데
예시가 3개 뿐이긴했지만 항상 같은 결과가 나오는 상황을 맞이했다..
아마도 적은 수의 데이터일 경우 성능상 맨 처음에 우선적으로 나오는 듯 하다..
참조
반응형