검색과 매칭
특정 속성이 데이터 집합에 있는지 여부를 검색하는 데이터 처리도 자주 사용된다.
- 스트림 API
- allMatch
- anyMatch
- noneMatch
- findFirst
- findAny
Predicate가 적어도 한 요소와 일치하는가 ?
- 프레디케이트가 주어진 스트림에서 적어도 한 요소와 일치하는지 확인할 때 :
anyMathc
메서드를 이용한다.
➡️ menu에 채식요리가 있는지 확인한다
if(menu.stream().anyMatch(Dish::isVegetarian)){
System.out.println("The menu is (someWhat) vegetarian friendly!!");
}
※anyMatch
는 불리언을 반환하므로 최종 연산이다.
프레디케이트가 모든 요소와 일치하는 검사
allMatch
메서드
스트림의 모든 요소가 주어진 프레디케이트와 일치하는지 검사한다.
예) 메뉴가 건강식(모든 요리가 1000칼로리 이하면 건강식으로 간주하겠다)인지 확인할 수 있다.
boolean isHealthy = menu.stream().allMatch(dish -> dish.getCalories() < 1000);
➡️ 결과 : true
noneMatch
noneMatch는 allMatch와 반대 연산을 수행한다.
noneMatch는 주어진 프레디케이트와 일치하는 요소가 없는지 확인한다.
boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories() >= 1000);
➡️ 결과 : true
anyMatch
,allMatch
,noneMatch
세 메서드는 스트림쇼트서킷 비법
, 즉 자바의 &&, ||와 같은 연산을 활용 활용한다.
요소 검색
findAny
- findAny 메서드는 현재스트림에서 임의의 요소를 반환한다.
- findAny 메서드를 다른 스트림과 연결해서 사용할 수 있다.
➡️ filter와 findAny를 사용해서 채식요리 선택 예제
Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();
스트림 파이프라인은 내부적으로 단일 과정으로 실행할 수 있도록 최적화된다. 즉 쇼트서킷
을 이용해서 결과를 찾는 즉시 실행을 종료한다.
Optional 이란 ? Optional
클래스(java.util.Optional)는 값의 존재나 부재 여부를 표현하는 컨테이너 클래스다. findAny는 아무 요소도 반환하지 않을 수 있다. Optional은 값이 존재하는지 확인하고 값이 값이 없을 때 어떻게 처리할지 강제하는 기능을 제공한다.
isPresent()는 Optional이 값을 포함하면 참(true)을 반환하고 값을 포함하지 않으면 거짓(false)을 반환한다.
isPresent(Consumer
T get()은 값이 존재하면 값을 반환하고, 값이 없으면 NoSuchElementException을 일으킨다.
T orElse(T other)는 값이 있으면 값을 반환하고, 값이 없으면 기본값을 반환한다.
➡️ 예시) Optional
menu.stream().filter(Dish::isVegetarian)
.findAny()
.ifPresent(dish -> System.out.println(dish.getName()));
첫 번째 요소 찾기
리스트 또는 정렬된 연속 데이터로부터 생성된 스트림처럼 일부 스트림에는 논리적인 아이템 순서가 정해져 있을 수 있다.
이런 스트림에서 첫 번째 요소를 찾으려면 어떻게 해야할까 ?
➡️ 예) 숫자 리스트에는 3으로 나누어떨어지는 첫 번째 제곱값을 반환하는 코드
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstSquareDivisibleByThree = someNumbers.stream()
.map(n -> n * n).filter(n -> n % 3 ==0)
.findFirst();
➡️결과 : 9
findFirst와 FindAny는 언제 사용할까 ?
findFirst와 findAny 메서드가 모두 필요갈까 ? 이유는 병렬성 때문이다. 병렬 실행에서는 첫 번째 요소를 찾기 어렵다. 따라서 요소의 반환 순서가 상관없다면 병렬 스트림에서는 제약이 적은 findAny를 사용한다.