JAVA - 람다와 스트림(10)

ch4570·2022년 11월 24일
1
post-thumbnail

groupingBy( )에 의한 분류

stuStream이라는 스트림이 있다고 가정하고, stuStream을 반 별로 그룹지어 Map에 저장하는 방법은 아래와 같다.

// 반 별로 그룹화 - groupingBy() 예제
Map<Integer, List<Student>> stuByBan = stuStream
			.collect(groupingBy(Student::getBan)); // toList()가 생략됨
  • groupingBy( )로 그룹화를 하면 List<T>에 담겨서 반환된다.
  • toList( )는 생략할 수 있다.
  • toList( )대신 toSet( )이나 toCollection( )을 사용할 수도 있다.
// 반별로 그룹화를 하고 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)
        ));

Collector 구현하기

  • Collector 인터페이스의 정의
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( )보다 유리하다.

출처 : 자바의 정석 3rd Edition(남궁성 저, 도우출판)

profile
Junior. Back-End Developer로 근무중인 서창희 입니다.

0개의 댓글