JAVA/스트림

스트림의 그룹화와 분할

chanhee01 2023. 8. 9. 00:55

partitioningBy() - 스트림을 두 개로 분할한다.

groupingBy() - 스트림을 n 개로 분할한다.

 

둘 다 Collectors에 있는 메서드이다. 전체가 아니라 나눈 다음에 그룹별로 무언가를 할 수 있는게 장점이기 때문에 이번 포스팅에서는 그것에 대해서 쓸 것이다.

 

 

partitioningBy() - 스트림을 두 개로 분할

Map<Boolean, List<Student>> stuBySex = stuStream
                     .collect(partitioningBy(Student::isMale)); // 학생들을 성별로 분할함
List<Student> maleStudent   = stuBySex.get(true);   // Map에서 남학생만 가져옴
List<Student> femaleStudent = stuBySex.get(false);  // Map에서 여학생만 가져옴

student 생성자에서 남자면 true, 여자면 false로 생성을 한 다음에 이 값으로 스트림을 2개로 분할을 할 수 있다.

 

 

 

Map<Boolean, Long> stuBySex = stuStream
                     .collect(partitioningBy(Student::isMale), Collectors.counting()); // 분할과 통계
System.out.println("남학생 수 :"+ stuBySex.get(true);   // 남학생 수 : 15
System.out.println("여학생 수 :"+ stuBySex.get(false);  // 여학생 수 : 13

타입을 Long으로 바꿔주면 counting을 통해 숫자를 찾아올 수 있다.

 

 

 

 

다중 분할 (100점 이하를 성별로 분할)

Map<Boolean, Map<Boolean, List<Student>>> failedStuBySex = Stream.of(stuArr)
           .collect(partitioningBy(Student::isMale,
                partitioningBy(s -> s.getScore() <= 100))
           );
           
List<Student> failedMaleStue    = failedStuBySex.get(true).get(true);
List<Student> failedFemaleStue  = failedStuBySex.get(false).get(true);

failedStuBySex의 첫 번째 get은 성별을, 두 번 째 get은 성적이 100점이하인 조건이다.

 

 

 

 

 

 

groupingBy() - 스트림을 n 개로 분할

Map<Integer, List<Student>> stuByBan = stuStream
                 .collect(groupingBy(Student::getBan, toList())); // 학년 상관 없이 반으로만 구분

groupingBy()는  partitioninigBy()랑 크게 다르지가 않다. 2개로 분할 하는 것이 아니라 여러개로 분할한다는 차이점만 있기 때문이다.

 

 

 

다중 그룹화 (1. 학년별 그룹화, 2. 반별 그룹화)

Map<Integer, Map<Integer, List<Student>>> stuByHakAndBan = stuStream
              .collect(groupingBy(Student::getHak,
                       groupingBy(Student::getBan)
              ));  // 학년과 반으로 그룹을 나누기
              
              
for(Map<Integer, List<Student>> hak : stuByHakAndBan.values()) {
    for(List<Student> ban : hak.values()) {
        System.out.println();
        for(Student s : ban)
            System.out.println(s);
    }
} // 다중 그룹화를 출력

그룹을 만들어서 학년, 반별로 다중 그룹화를 할 수가 있다.