Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

groupingBy와 partitioningBy 비교 #48

Open
jaejae-yoo opened this issue Apr 5, 2022 · 1 comment
Open

groupingBy와 partitioningBy 비교 #48

jaejae-yoo opened this issue Apr 5, 2022 · 1 comment
Assignees
Labels
ch6 about chapter 6

Comments

@jaejae-yoo
Copy link

문제

groupingBy와 partitioningBy의 차이점 및 공통점

선정 배경

책에서 groupingBy와 partitioningBy 컬렉터의 비슷한 점에 대해 언급하고 있습니다.
둘의 비슷한 점과 차이점에 대해 더 알아보고 정리해 보고자 주제로 선정하였습니다.

관련 챕터

[6장] 스트림으로 데이터 수집 221p

@jaejae-yoo jaejae-yoo self-assigned this Apr 5, 2022
@jaejae-yoo jaejae-yoo added the ch6 about chapter 6 label Apr 5, 2022
@jaejae-yoo
Copy link
Author

그룹화 : 스트림의 요소를 특정 기준으로 그룹화한다.
분할 : 스트림의 요소를 참, 거짓 두 그룹으로 분할하는 것이다.

1. 그룹화: gropingBy - 스트림의 요소를 Function으로 분류

그룹화

Map<Dish, Type, List<Dish>> caloricDishesByType = menu.stream()
        .collect(groupingBy(Dish::getType, filtering(dish -> getCalrories() > 500, toList())));
//caloricDishesByType : {OTHER=[french fries, pizza], MEAT=[pork, beef], FISH=[]}

스트림의 각 요리에서 Dish.Type과 일치하는 모든 요리를 추출하는 함수를 groupbingBy 메서드로 전달했다.
이 함수를 기준으로 스트림이 그룹화되므로 이를 분류함수라고 부른다.

다수준 그룹화

    Map<Dish.Type, Map<CalricLevel, List<Dish>>> dishesByTypeCaloricLevel = menu.stream().collect(
            groupingBy(Dish::getType, 
                    groupingBy(dish -> { 
                if (dish.getCalories() <= 400) 
                    return CaloricLevel.DIET; 
                else if (dish.getCalories() <= 700) 
                    return CaloricLevel.NORMAL;else return CaloricLevel.FAT; 
                    })
            )
    );
//dishesByTypeCaloricLevel : //{MEAT={DIET=[chicken], NORMAL=[beef], FAT=[pork]}, FISH={DIET=[prawns], NORMAL=[salmon]}, OTHER={...}}

2. 분할: partitioningBy - 스트림의 요소를 Predicate으로 분류

Map<Boolean, List<Dish>> partitionedMenu = menu.stream()
                .collect(partitioningBy(Dish::isVegetarian));
// {false=[pork, beef, chicken, prawns, salmon], // true=[french fires, rice, season fruit, pizza]}

분할은 프레디케이트를 분류 함수로 사용하는 특수한 그룹화 기능이다.
해당 분할 함수는 불리언을 반환하므로 맵의 키 형식은 Boolean이며 참, 거짓의 두 개의 그룹으로 분류된다.

다수준 분할

menu.stream()
        .collect(partitioningBy(Dish::isVegetarian), partitioningBy(d -> d.getCalories() > 500));
// {false={false=[chicken, prawns, salmon], true=[pork, beef]}, true={false=[rice, season fruit], true=[french fires, pizza]}}

가능할까?

menu.stream()
        .collect(partitioningBy(Dish::isVegetarian), partitioningBy(Dish::getType));

분류를 Function으로 하느냐 Predicate로 하느냐의 차이만 있을 뿐 동일하다.
스트림을 두 개의 그룹으로 나눠야 한다면 partitioningBy로 분할하는 것이 더 빠르다고 한다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ch6 about chapter 6
Projects
None yet
Development

No branches or pull requests

1 participant