Open jaejae-yoo opened 2 years ago
그룹화 : 스트림의 요소를 특정 기준으로 그룹화한다. 분할 : 스트림의 요소를 참, 거짓 두 그룹으로 분할하는 것이다.
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={...}}
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로 분할하는 것이 더 빠르다고 한다.
문제
groupingBy와 partitioningBy의 차이점 및 공통점
선정 배경
책에서 groupingBy와 partitioningBy 컬렉터의 비슷한 점에 대해 언급하고 있습니다. 둘의 비슷한 점과 차이점에 대해 더 알아보고 정리해 보고자 주제로 선정하였습니다.
관련 챕터
[6장] 스트림으로 데이터 수집 221p