Predicate로의 필터링과 고유요소로의 필터링이 있다.List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian)
.collect(toList());
List<Integer> numbers = Arrays.asList(1,2,3,4,5,3,3,2,4);
numbers.stream()
.filter(i -> i%2 == 0)
.distinct()
.forEach(System.out::println);
TAKEWHILE 과 쓰임새가 비슷하나, 처음으로 거짓이 되는 지점까지 발견된 요소를 버림map 과 flatMap 메소드를 지원List<String> dishNames = menu.stream()
.map(dish::getName) // Menu 객체가 아닌, map을 이용해 String 객체만 뽑아냄
.collect(toList());
String[] words = {"Hello","World"}
List<Integer> words = stream()
.map(word -> word.split("")) //{"H","E","L","L","O","W","O","R","L","D"}
.distinct() //{"H","E","L","O","W","R","D"}
.collect(toList()); //{}"HELLOWRD"}
| 메소드 | 설명 | 사용법 |
|---|---|---|
| anyMatch(Preicate<T> p ) | Preicate가 주어진 스트림에서 적어도 한 요소와 일치하는지 확인할 때 사용 | menu.stream().anyMatch(Dish::Vegetarian) |
| allMatch(Predicate<T>) | Predicate가 주어진 스트림에서 모든 요소와 일치하는지 검사 | menu.stream().allMatch(Dish::Vegetarian) |
| noneMatch(Predicate<T>) | Predicate가 주어진 스트림에서 모든 요소와 일치하지 않는지 검사 | 사용법 같음 |
| findAny(Predicate<T>) | Predicate가 주어진 스트림에서 만족하는 요소를 찾는 즉시 반환하고 종료 | |
| findFirst(Predicate<T>) | Preicate가 주어진 스트림에서 만족하는 요소 중 첫번째 요소를 반환 |
쇼트서킷 평가
전체 스트림을 처리하지 않았더라도 스트림의 결과를 반환하는 것. 원하는 요소를 찾았으면 즉시 결과를 반환하여 속도를 높이는 유용한 연산이고
allMatch,noneMatch,findFirst,findAny등의 연산이 해당 기법을 사용한다.
findAny(), findFirst()?
findAny(), findFirst() 중 둘 중 무엇을 사용해도 상관이 없다면 findAny()를 사용한다. 이유는 병렬성 때문이다. 병렬실행에서는 첫 번째 요소를 찾기 어렵다. 따라서 요소의 반환 순서가 상관없다면 병렬 스트림에서는 제약이 적은
findAny를 사용한다.
BinaryOperator<T> int sum = numbers.stream().reduce(0 , (a,b) -> a+ b);
Optional<Integer> sum = numbers.stream().reduce((a,b)-> a+b);
다만 Optional을 사용하여 null 일 상황을 방지하여 주자.
Optional<Integer> max = numbers.stream().reduce(Integer::max);
Optional<Integer> min = numbers.stream().reduce(Integer::min);
reduce를 사용하여 연산시 내부 구현에서 병렬로 reduce를 실행할 수 있다.
병렬로 reduce를 이용하기 위해서는 해당 변수가 공유되는 환경이기 때문에 동기화를 시켜야 한다. 동기화를 시키기 위해서 결국 병렬화로 얻어야 할 이득이 스레드 간의 소모적 경쟁 때문에 상쇄되어 버림. 따라서 해당 부분은 입력을 분할하고 분할된 입력을 더한다음 다시 합쳐야 한다. 해당 부분은 포크/조인 프레임워크를 이용하여 해결할 수 있다.