Не работает Collectors.groupingBy()
Есть лист List<Category> categories, в классе Category есть метод List<Product> getProducts(), который возвращает лист с продуктами, класс Product содержит в себе categoryName и price, так вот с помощью StreamApi нужно из categories создать мапу - Map<String categoryName, Long sumOfPrices>, которая содержит названия категорий и сумму цен продуктов в ней.
Но компилятор не дает сгенерировать следующий код
categories.stream()
.map(Category::getProducts)
.collect(Collectors.groupingBy(Product::getCategory))
примерная структура классов
public class Category {
private List<Product> products;
public List<Product> getProducts() {
return products;
}
}
public class Product {
private String categoryName;
private Long price;
public String getCategoryName() {
return categoryName;
}
public Long getPrice() {
return price;
}
}
Пример:
Products:
prod1(category: Category1, price: 45)
prod2(category: Category1, price: 55)
prod3(category: Category2, price: 45)
Вывод - Map<String, Long> sums:
Category1 - 100
Category2 - 45
Ответы (1 шт):
categories.stream()
.map(Category::getProducts)
Создает стрим из списков продуктов, а не просто стрим продуктов. Далее нам нужно развернуть стрим списков продуктов в стрим продуктов, а стрим продуктов перевести в мапу из продуктов, сгруппировать по ключу и суммировать по значению.
Map<String, Long> collect = categories
.stream()
.map(Category::getProducts)
.flatMap(products -> products.stream().map(product -> new AbstractMap.SimpleEntry<>(product.getCategory(), product.getPrice())))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.summingLong(Map.Entry::getValue)));