우리는 지금까지 최종연산에서 List 객체로 결괏값을 도출하기 위해
toList를 Collector 인터페이스의 구현으로 사용했다.
대표적인 예제가 collect(Collectors.toList());
이다.
그런데 어떻게 collect(Collectors.toList());
가 List 객체를 반환할 수 있었을까?
이 질문에 대한 대답으로,
컬렉터는 고급 리듀싱 기능을 수행한다.
즉, 리듀싱 연산을 이용해서 stream 흐름의 하나하나 요소를 방문하며 컬렉터가 작업을 처리한다.
(스트림 리듀싱 연산에 대해 모르시면,
https://velog.io/@dlsrjsdl6505/%EC%9E%90%EB%B0%94-8-Stream-%EB%A7%A4%EC%86%8C%EB%93%9C-%EC%98%88%EC%A0%9C
여길 참고하시면 된다.)
즉,
Collectors 클래스의 정적 팩토리 매서드를 임포트하고,
import static java.util.stream.Collectors.*;
스트림.collect(Collectors.toList());
//이렇게 위와 같이 작성하면,
//스트림 객체의 요소를 방문하며 내부적으로 리듀싱 연산을 수행해,
//요소 하나하나를 List객체로 만들게 된다.
스트림에 있는
객체의 숫자필드의 합, 평균을 반환하는 연산에도
내부적으로 리듀싱 기능이 사용되고,
이러한 연산을 요약 연산이라고 부른다.
int totalCalories = menu.stream()
.collect(summingInt(Dish::getCalories));
double aveCalories = menu.stream()
.collect(averagingInt(Dish::getCalories));
똑같이 칼로리의 총합을 구하는 연산이어도, 아래와 같이 여러개가 가능하다.
int totalCaloires = menu.stream().collect(reducing(0, Dish::getCaloires, Integer::sum));
int totalCaloires = menu.stream().mapToInt(Dish::getCalories).sum();
int totalCaloires = menu.stream().map(Dish::getCalories).reduce(Integer::sum).get();