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를 이용하기 위해서는 해당 변수가 공유되는 환경이기 때문에 동기화를 시켜야 한다. 동기화를 시키기 위해서 결국 병렬화로 얻어야 할 이득이 스레드 간의 소모적 경쟁 때문에 상쇄되어 버림. 따라서 해당 부분은 입력을 분할하고 분할된 입력을 더한다음 다시 합쳐야 한다. 해당 부분은 포크/조인 프레임워크를 이용하여 해결할 수 있다.