06. 스트림으로 데이터 수집
간단 정리#
- collector는 스트림 요소를 요약 결과로 누적하는 다양한 방법을 인수로 갖는 최종 연산
 - 스트림 요소를 하나의 값으로 리듀스하고 요약하는 다양한 컬렉터가 미리 정의되어 있음
 - 스트림 요소 그룹화: 
groupingBy() - 스트림 요소 분할: 
partitioningBy() - 컬렉터는 다수준의 그룹화, 분할, 리듀싱 연산에 적합하게 설계되어 있음
 - 커스텀 컬렉터를 Collector 인터페이스를 구현함으로 구현 가능
 
Collectors 클래스로 컬렉션 만들고 사용#
Collector 란#
- Collector 인터페이스 구현은 스트림의 요소를 어떤 식으로 도출할지 지정한다
 
Collector 특징#
- 가독성과 유지보수성을 증가시킬 수 있음
 collect를 호출하면 리듀싱 연산이 일어남
미리 정리된 컬렉터#
Collectors에 미리 리듀싱을 위해 팩터리 메서드들이 정리되어 있음Collectors기능 세 가지- 요약: 스트림 요소를 하나의 값으로 리듀스
 - 요소 그룹화
 - 요소 분할
 
요약: 하나의 값으로 데이터 스트림 리듀스하기#
정적 팩터리 메서드#
counting()minBy()maxBy()summingInt()averagingInt()summarizingInt()- 기본 타입인 int, long, double 지원
 
joining()- 문자열 하나로 합치기
 
특별한 리듀싱 요약 연산#
reducing()- 파라미터로 초깃값, 변환 함수, 합계 함수를 받음
 - 파라미터가 하나로 구성될 땐 합계 함수만 사용됨
- 초깃값은 원소 첫번째
 - 변환함수는 항등함수 (
e -> e) 
 
데이터 그룹화와 분할#
그룹화: 데이터 집합을 하나 이상의 특성으로 분류해서 그룹화하는 연산
그룹화#
groupingBy()#
아래의 예제에서 Dish::getType 과 같이 분류 기준이되는 함수를 분류함수 라 함
일반적인 방식
groupingBy() 의 두번째 인자로 filtering mapping flatMapping 등 분류화 결과 값에 대한 람다를 활용할 수 있음
Collector 형식의 두번째 인자 활용
다수준 그룹화#
중첩 맵을 만들어야할 때 활용 가능
분할#
- 분할 함수는 
Predicate를 활용함 - 두번째 인자는 groupingBy 와 같이 분할할 대상의 결과 값을 추출할 람다를 활용할 수 있음
 
분할 장점#
- 참, 거짓에 대한 스트림 리스트를 모두 유지함
 
자신만의 커스텀 컬렉터 개발#
Collector 인터페이스를 구현하여 자신만의 커스텀 컬렉터를 개발할 수 있음
Collector 인터페이스#
리듀싱 연산에 대한 함수 정의들로 이루어짐
Collector 인터페이스
- 타입 설명
- T: 수집될 스트림 항목의 제네릭 형식
 - A: 누적자, 수집 과정에 중간 결과를 저장할 객체 형식
 - R: 수집 연산 결과에 대한 객체 형식
 
 Characteristics설명- UNORDERED: 리듀싱 결과는 입력 요소 순서를 보장하지 않음
 - CONCURRENT: 다중 스레드 가능
 - IDENTITY_FINISH: 정의되어 있을시 finisher는 항등 함수, 즉 
Function.identity()를 리턴하도록 구성되어 있음을 알림