stuStream이라는 스트림이 있다고 가정하고, stuStream을 반 별로 그룹지어 Map에 저장하는 방법은 아래와 같다.
// 반 별로 그룹화 - groupingBy() 예제
Map<Integer, List<Student>> stuByBan = stuStream
.collect(groupingBy(Student::getBan)); // toList()가 생략됨
// 반별로 그룹화를 하고 List로 반환받는 예제
Map<Integer, List<Student>> stuByBan = stuStream
.collect(groupingBy(Student::getBan), toList()); // toList() 생략가능
// 학년별로 그룹화를 하고 Set으로 반환받는 예제(toCollection() 사용)
Map<Integer, HashSet<Student>> stuByHak = stuStream.
.collect(groupingBy(Student::getHak), toCollection(HashSet::new)));
stuStream을 성적의 등급에 따라 그룹화를 할 수도 있다.
HIGH, MID , LOW 세 종류의 기준에 따라서 람다식을 사용해 조건식을 등급별로 분류하여 집계할 수 있다.
// 복잡한 그룹화 예제
Map<Student.Level, Long> stuByLevel = stuStream
.collect(groupingBy(s -> {
if(s.getScore() >= 200) return Student.Level.HIGH;
elss if(s.getScore() >= 100) return Student.Level.MID;
else return Student.Level.LOW;
}, counting())
);
groupingBy( )를 여러 번 사용해서, 다수준 그룹화도 가능하다.
// 학년별 그룹화 후 반별 그룹화 예제
Map<Integer, Map<Integer,Student>> StuByHakAndBan = stuStream
.collect(groupingBy(Student::getHak,
groupingBy(Student::getBan)
));
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A,T> accumulator();
BinaryOperator<A> combiner();
Function<A, R> finisher();
Set<Characteristics> characteristics(); // 컬렉터의 특성이 담긴 Set을 반환
...
}
구현해야 할 메서드는 총 5개인데, characteristics( )를 제외하면 모두 람다식을 작성하면 된다.
characteristics( )는 컬렉터가 수행하는 작업의 속성에 대한 정보를 제공하는 메서드이다.
아래의 3가지 속성 중에서 해당하는 것을 Set에 담아서 반환하면 된다.
💡 collect( )는 그룹화와 분할, 집계 등에 유용하게 쓰이며 병렬화에 있어서는 reduce( )보다 유리하다.