더북(TheBook)

• 마지막으로, reducing 메서드들은 다운스트림 요소들에 범용 리덕션을 적용한다. 세 가지 메서드 형태 reducing(binaryOperator), reducing(identity, binaryOperator), reducing(identity, mapper, binaryOperator)가 있다. 첫 번째 형태에서는 항등값이 null이다(항등 파라미터가 없으면 Optional 결과를 돌려주는 Stream::reduce의 형태와는 다르다는 점을 주목하기 바란다). 세 번째 형태에서는 mapper 함수가 적용되고 이 함수의 값이 리듀스된다.

 

다음은 각 주에 있는 모든 도시의 이름을 콤마 분리 문자열로 얻는 예제다. 여기서는 각 도시를 이름으로 맵핑해서 이름들을 연결한다.


Map<String, String> stateToCityNames = cities.collect(

groupingBy(City::getState,

reducing("", City::getName,

(s, t) -> s.length() == 0 ? t : s + ", " + t)));


 

Stream.reduce와 마찬가지로, Collectors.reducing은 거의 사용할 필요가 없다. 이 예제에서는 다음과 같은 코드로 같은 결과를 좀 더 자연스럽게 얻을 수 있다.


Map<String, String> stateToCityNames = cities.collect(

groupingBy(City::getState,

mapping(City::getName,

joining(", "))));


 

솔직히 다운스트림 컬렉터는 아주 난해한 표현식을 야기할 수 있다. 따라서 ‘다운스트림’ 맵 값들을 처리하기 위해 반드시 groupingBy 또는 partitioningBy와 연계해서 사용해야 한다. 그렇지 않으면, 단순히 map, reduce, count, max, min 같은 메서드를 스트림에 직접 적용한다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.