我有一个名为Food
的课程:
public class Food {
private Collection<FoodToFoodGroup> foodToFoodGroups;
//getters and setters
}
FoodToFoodGroup
看起来像这样:
public class FoodToFoodGroup {
private Food food;
private FoodGroup foodGroup;
//getters and setters
}
最后,每个FoodGroup
都有一个名称:
public class FoodGroup {
private String name;
//getters and setters
}
这些类是通过hibernate映射的所有实体。我通过调用Food
收集了数据库中所有foodRepository.findAll()
个实体的集合,并且我尝试按照Food
的名称对所有FoodGroup
个实例进行分组,最终得到Map<String, Collection<Food>>
。我试图通过Stream API执行此操作,但无法使用Collectors.groupingBy
收集器来实现此目的。
Map<String, Collection<Food>> foodsByFoodGroupName =
foodRepository.findAll().stream()
.collect(Collectors.groupingBy(
//what goes here?
));
请注意,Food
可以包含多个FoodGroup
个,因此我需要多个Food
中的任何FoodGroup
以多个Collection
显示生成Map
中的{1}}。这可以通过Stream API和Collectors.groupingBy()
吗?
示例
如果我有以下食物:
Food: Pimento Cheese
- FoodToFoodGroups: [
- FoodGroup: cheese,
- FoodGroup: dairy
]
Food: Chocolate Milk
- FoodToFoodGroups: [
- FoodGroup: milk,
- FoodGroup: dairy
]
我希望生成的Map
看起来像这样:
Key: cheese
- Collection<Food>: [Pimento Cheese]
Key: milk
- Collection<Food>: [Chocolate Milk]
Key: dairy
- Collection<Food>: [Pimento Cheese, Chocolate Milk]
答案 0 :(得分:1)
是你正在寻找的
foodRepository.findAll().stream()
.map(Food::getFoodToFoodGroup)
.flatMap(Collection::stream)
.collect(Collectors.groupingBy(
f -> f.getFoodGroup().getName(),
HashMap::new,
Collectors.mapping(FoodToFoodGroup::getFood, Collectors.toList())));
答案 1 :(得分:0)
I don't think groupingBy
is what you want here, since it is not designed for putting the same item in multiple groups.
For a not-purely-functional solution using streams, you could flat-map each Food
to a foodGroupToFood
entry set, then add all of the pairs to a map using a BiConsumer
.
BiConsumer<Map<FoodGroup, Set<Food>>, Map.Entry<FoodGroup, Food>> addEntryToMapOfSets = (map, entry) -> {
if (map.containsKey(entry.key()))
map.get(entry.key()).add(entry.value());
else
foodGroupToFoods.put(entry.key(), Stream.of(entry.value()).collect(Collectors.toSet()))
};
Map<String, Collection<Food>> foodGroupToFoods = new HashMap<>();
foods.stream()
.flatMap(food -> food.getFoodToFoodGroup().stream()
.collect(Collectors.toMap(pair -> pair.foodGroup, pair -> pair.food))
.entrySet())
.forEach(entry -> addEntryToMapofSets(foodGroupToFoods, entry));
Disclaimer: I haven't written in Java in a while, please correct my usage of Streams API if it needs correction. Edit: This is probably more complicated than it needs to be.