그룹화와 분할
그룹화 : 스트림의 요소를 특정 기준으로 그룹화 하는것
분할 : 스트림의 요소를 두가지, 지정한 조건에 일치하는 그룹과 일치하지 않는 그룹으로 분할하는것
그룹화 메서드 groupingBy()
Collector groupingBy(Function classifier)
Collector groupingBy(Function classifier, Collecctor downstream)
Collector grooupingBy(Function classifier, Supplier mapFactory, Collector downstream)
분할 메서드 partitioningBy()
Collector partitioningBy(Predicate predicate)
Collector partitioningBy(Predicate predicate, Collecctor downstream)
그룹화인 groupingBy()의 경우 Function을 매개변수로 받고 분할인 partitioningBy()의 경우 Predicate를 매개변수로 받는다. 스트림을 두개의 그룹으로 나눠야하는 경우 partitioningBy()가 더 빠르다.
그룹화와 분할의 결과는 Map에 담겨 반환된다.
partitioningBy()에 의한 분류
위처럼 코드가 있을경우 partitioningBy() 사용예시이다.
Map<Boolean, List<Student>> stuBySex = stuStream.collect(partitioningBy(Student::isMale));
List<Student> maleStudent = stuBySex.get(true);
List<Student> femaleStudent = stuBySex.get(flase);
각각 남자학생일경우, 여학생일 경우 List이다. Student객체에 boolean으로 초기화 되어있는 값을 확인하여 partitioningBy에서 분할한다.
성별 학생수 구하기
Map<Boolean, Long> stuNumBySex = stuStream.collect(partitioningBy(Student::isMale, counting());
System.out.println("남학생 수 : "+ stuNmBySex.get(true));
System.out.println("여학생 수 : "+ stuNmBySex.get(false));
성별 1등학생 구하기
Map<Boolean, Optional<Stuudent>> topScoreBySex = stuStream
.collect(partitioningBy(Student::isMale,maxBy(comparingInt(Student::getScore)));
System.out.println("남학생 수 : "+ topScoreBySex.get(true));
System.out.println("여학생 수 : "+ topScoreBySex.get(false));
150점 아래 학생들만 출력
Map<Boolean, Map<Boolean, List<Student>>> failedStuBySex = stuStream
.collect(partitioningBy(Student::isMale, partitioningBy(s -> s.getScore() < 150)));
List<Student> failedMaleStu = failedStuBySex.get(true).get(true);
List<Student> failedFemaleStu = failedStuBySex.get(false).get(true);
groupingBy()에 의한 분류
학생들을 반별로 그룹짓기
Map<Integer, List<Student>> stuByBan = stuStream.collect(groupingBy(Student::getBan));
groupingBy()로 그룹화를 하면 기본적으로 List<T>에 값을 담는다.
toList()를 매개변수로 넣어주어도되고 필요에 따라 toSet()이나 toCollection(HashSet::new) 등을 사용할 수 있다.
ex)
Map<Integer, List<Student>> stuuByBan = stuStream.collect(groupingBy(Student::getBan, toList()));
Map<Integer, HashSet<Student>> stuByHak = stuStream
.collect(groupingBy(Studuent::getHak,toCollection(HashSet::new)));
분할과 그룹화는 많이써봐야할것같다. 이해는 되지만 사용하지않은 상황에서 응용이 어렵게 느껴진다.
'Programming > JAVA' 카테고리의 다른 글
바이트 기반 스트림 (0) | 2021.09.10 |
---|---|
자바의 입출력 (0) | 2021.09.10 |
collect() (0) | 2021.09.02 |
스트림의 최종연산 (0) | 2021.09.01 |
Optional (0) | 2021.08.25 |