I'm learning java stream grouping and don't really know the keyword to search for my problem. I have a Product class:
class Product {
private String name;
private List<String> types;
}
I have a list of products:
List<Product> products = new ArrayList<>();
List<String> type1 = new ArrayList<>();
type1.add("typeA");
type1.add("typeB");
products.add(new Product("product1", type1));
List<String> type2 = new ArrayList<>();
type2.add("typeB");
type2.add("typeC");
products.add(new Product("product2", type2));
List<String> type3 = new ArrayList<>();
type3.add("typeA");
type3.add("typeC");
products.add(new Product("product3", type3));
By using stream, how can I get a map grouping by type of products:
{
"typeA": [product1, product3],
"typeB": [product1, product2],
"typeC": [product2, product3]
}
Thank you
You can use the Collectors.groupingBy() method to group the products by their types.
Map<String, List<Product>> productsByType = products.stream()
.flatMap(p -> p.getTypes().stream().map(t -> new AbstractMap.SimpleEntry<>(t, p)))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
The code is creating a map that groups products by their types. It does this by first transforming the list of products into a stream of key-value pairs, where each key is a product type and each value is the corresponding product. It then collects these key-value pairs into a map using the groupingBy() method, with the product type as the key and a list of products that have that type as the value.
To create the key-value pairs in the stream, the code uses the AbstractMap.SimpleEntry class, which is a simple way to represent a key-value pair. Finally, the code assumes that there is a method in the Product class that returns the list of product types.
You can print them and get your expected result by forEach method
productsByType.forEach((k,v)-> System.out.println(k + " " + v));
also don't forget to override toString method on the product class
@Override
public String toString() {
return name;
}