•
이 장에서는 스트림의 요소를 선택하거나 스킵하는 다양한 방법을 설명한다.
◦
프레디케이트를 이용하는 방법
◦
스트림의 처음 몇 개의 요소를 무시하는 방법
◦
특정 크기로 스트림을 줄이는 방법
•
다양한 방법을 이용해 효율적으로 작업을 수행할 수 있다.
1. 프레디케이트를 이용한 슬라이싱
•
스트림의 요소를 효과적으로 선택할 수 있도록 takeWhile, dropWhile 두 가지 새로운 메서드를 자바 9부터 지원하기 시작했다.
•
takeWhile 활용
◦
다음과 같은 요리 목록이 있다고 가정하자.
List<Dish> specialMenu = Arrays.asList(
new Dish("seasonal fruit", true, 120, Dish.Type.OTHER),
new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("rice", true, 350, Dish.Type.OTHER),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french fries", true, 530, Dish.Type.OTHER));
Java
복사
▪
어떻게하면 여기서 320칼로리 이하의 요리를 선택할 수 있을까?
▪
우린 본능적으로 앞에서 사용했던 filter 메서드를 사용할 것이다.
▪
다른 방법도 있다. 위 리스트는 이미 칼로리 순으로 정렬되어 있다는 사실이다.
•
filter 연산을 사용하면 각 스트림에 모두 filter를 적용시킨다.
•
정렬되어있다는 사실을 통해 320 칼로리 초과의 요리가 나오면 연산을 중단시킬 수 있지 않을까?
•
takeWhile 연산을 사용하면 해당 연산이 가능하다.
List<Dish> slicedMenu1 = specialMenu.stream()
.takeWhile(dish -> dish.getCalories() < 320)
.collect(toList());
Java
복사
•
dropWhile 활용
◦
오히려 나머지 요소를 선택하려면 어떻게 해야할까?
◦
즉 320칼로리보다 큰 요소들을 구하고 싶다면 dropWhile을 이용해 이 작업을 완료할 수 있다.
List<Dish> slicedMenu2 = specialMenu.stream()
.dropWhile(dish -> dish.getCalories() < 320)
.collect(toList());
Java
복사
◦
dropWhile은 takeWhile과 정반대의 작업을 수행한다.
◦
dropWhile은 프레디케이트가 처음으로 거짓이되는 지점까지 발견된 요소를 버린다.
◦
프레디케이트가 거짓이되면 그 지점에서 작업을 중단하고 남은 모든 요소를 반환한다.
2. 스트림 축소
•
스트림은 주어진 값 이하의 크기를 갖는 새로운 스트림을 반환하는 limit(n) 메서드를 지원한다.
•
스트림이 정렬되어 있다면 최대 요소 n개를 반환할 수 있다.
◦
예를 들어 다음처럼 300 칼로리 이상의 세 요리를 선택해서 리스트를 만들 수 있다.
List<Dish> dished = specialMenu.stream()
.filter(dish -> dish.getCalories() > 300)
.limit(3)
.collect(toList());
Java
복사
▪
filter와 limit을 조합한 모습을 보여준다.
▪
프레디케이트와 일치하는 처음 세 요소를 선택하고 결과를 반환한다.
▪
limit은 정렬되지 않은 스트림에도 사용이 가능한데, 소스가 정렬되어 있지 않다면 limit의 결과도 정렬되지 않은 상태로 반환된다.
3. 요소 건너뛰기
•
스트림은 처음 n개 요소를 제외한 스트림을 반환하는 skip(n) 메서드를 지원한다.
•
n개 이하의 요소를 포함하는 스트림에 skip(n)을 호출하면 빈 스트림이 반환된다.
◦
limit(n)과 skip(n)은 상호 보완적인 연산을 수행한다.
◦
예를 들어 다음 코드는 300 칼로리 이상의 처음 두 요리를 건너뛰고 300 칼로리가 넘는 나머지 요리를 반환한다.
List<Dish> dishes = menu.stream()
.filter(d -> d.getCaloreis() > 300)
.skip(2)
.collect(toList());
Java
복사