How to create Map<String,List<Product>> of below. Here, String (key of the Map) is the category of a Product.
One product can belong to multiple categories, like in the example below.
I am trying with below code, however not able to get next operation:
products.stream()
.flatMap(product -> product.getCategories().stream())
. // how should I progress from here?
Result should be like below:
{electonics=[p1,p3,p4], fashion=[p1,p2,p4], kitchen=[p1,p2,p3], abc1=[p2], xyz1=[p3],pqr1=[p4]}
Product p1 = new Product(123, Arrays.asList("electonics,fashion,kitchen".split(",")));
Product p2 = new Product(123, Arrays.asList("abc1,fashion,kitchen".split(",")));
Product p3 = new Product(123, Arrays.asList("electonics,xyz1,kitchen".split(",")));
Product p4 = new Product(123, Arrays.asList("electonics,fashion,pqr1".split(",")));
List<Product> products = Arrays.asList(p1, p2, p3, p4);
class Product {
int price;
List<String> categories;
public Product(int price) {
this.price = price;
}
public Product(int price, List<String> categories) {
this.price = price;
this.categories = categories;
}
public int getPrice() {
return price;
}
public List<String> getCategories() {
return categories;
}
}
If you want to use collector
groupingBy()for some reason, then you can define a wrapper class (with Java 16+ a record would be more handy for that purpose) which would hold a reference to a category and a product to represent every combination category/product which exist in the given list.Pre-Java 16 alternative:
And then in the make use of the combination of collectors
mapping()andtoList()as the downstream collector ofgroupingBy().A link to Online-Demo
But instead of creating intermediate objects and generating nested streams, the more performant option would be to describe the accumulation strategy within the three-args version of
collect()(or define a custom collector).That's how it might be implemented:
A link to Online-Demo