/////
Search
Duplicate
2️⃣

스트림 슬라이싱

이 장에서는 스트림의 요소를 선택하거나 스킵하는 다양한 방법을 설명한다.
프레디케이트를 이용하는 방법
스트림의 처음 몇 개의 요소를 무시하는 방법
특정 크기로 스트림을 줄이는 방법
다양한 방법을 이용해 효율적으로 작업을 수행할 수 있다.

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
복사
dropWhiletakeWhile과 정반대의 작업을 수행한다.
dropWhile은 프레디케이트가 처음으로 거짓이되는 지점까지 발견된 요소를 버린다.
프레디케이트가 거짓이되면 그 지점에서 작업을 중단하고 남은 모든 요소를 반환한다.

2. 스트림 축소

스트림은 주어진 값 이하의 크기를 갖는 새로운 스트림을 반환하는 limit(n) 메서드를 지원한다.
스트림이 정렬되어 있다면 최대 요소 n개를 반환할 수 있다.
예를 들어 다음처럼 300 칼로리 이상의 세 요리를 선택해서 리스트를 만들 수 있다.
List<Dish> dished = specialMenu.stream() .filter(dish -> dish.getCalories() > 300) .limit(3) .collect(toList());
Java
복사
filterlimit을 조합한 모습을 보여준다.
프레디케이트와 일치하는 처음 세 요소를 선택하고 결과를 반환한다.
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
복사