Map<Dish.Type, List<Dish>> dishesByTpe =
menu.stream().collect(groupingBy(Dish::getType));
System.out.println("________"+dishesByTpe);
____{MEAT=[pork, beef, chicken], OTHER=[french fries, rice, season fruit, pizza], FISH=[prawns, salmon]}
Collectors.groupingBy를 사용해서 그룹화할 수 있다.
또한 람다식으로 조건도 추가할 수 있다
public enum CaloricLevel { DIET, NORMAL, FAT }
Map<CaloricLevel, List<dish<< dishesByCaloricLevel = menu.stream()
.collect(groupingBy(dish -< P
if( dish.getCalories() <= 400 ) return CaloricLevel.DIET;
else if (dish.getCalories() <= 700 ) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
})));```
이제 500 칼로리가 넘는 요리만 필터해보자
Map<Dish.Type, List<Dish>> caloricDishesByType =
menu.stream().collect(groupingBy(Dish::getType,
filtering(dish -> dish.getCalories() < 500, toList())));
또, flatMapping 컬렉터를 사용하면 각 형식의 요리 태그를 추출할 수 있다.
Map<Dish.Type, Set<String>> dishNamesByType =
menu.stream()
.collect(groupingBy(Dish::getType,
flatMapping(dish -> dishTags.get( dish.getName() ).stream(), toSet())));
그럼 두개로 분류도 가능한가? 예,,,쌉파서블입니다
Map<Dish.Type, Map<CaloricLevel, 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;
})
)
);
mapping이랑 같이 써볼까?
Map<Dish.Type, Set<CaloricLevel>> caloricLevelsByType =
map.stream().collect(
groupingBy(Dish::getType, mapping( dish -> {
if ( dish.getCalories() <= 400 ) return CaloricLevel.DIET;
else if(dish.getCalories() <- 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT; },
toSet() )));
mapping 메서드를 사용한 결과는
{OTHER=[DIET, NORMAL], MEAT=[DIET, NORMAL, FAT], FISH=[DIET, NORMAL]}
이렇게 생성된다.
게다가 toSet 대신에
Map<Dish.Type, Set> caloricLevelsByType =
menu.strea().collect(
groupingBy(Dish::getType, mapping(dish -> {
if(dish.getCalories() <= 400 ) return CaloricLevel.DIET;
else if(dish.getCalories() < = 700 ) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT; },
toCollection(HashSet::new) )));