I'm trying to use streams to get a map of a pojo to a Set of items exposed by a property on the pojo. I realise that isn't clear so I'll show how I've done it without streams.
I have and enum of product categories, and enum of Products and a list of shops with the product like this
public enum Category {
FRUIT, VEGITABLE, MEAT;
}
public enum Product {
APPLE ( Category.FRUIT ),
PEAR ( Category.FRUIT ),
BANANA ( Category.FRUIT ),
CARROT ( Category.VEGITABLE ),
POTATO ( Category.VEGITABLE ),
CABBAGE ( Category.VEGITABLE ),
MINCE ( Category.MEAT ),
CHOP ( Category.MEAT ),
STEAK ( Category.MEAT );
private final Category category;
Product( Category category ) {
this.category = category;
}
public String value() {
return name();
}
public static Product fromValue( String v ) {
return valueOf( v );
}
public Category getCategory() {
return this.category;
}
}
public class Shop {
private long id;
private String name;
private EnumSet<Product> products;
public Shop( long id, String name, Collection<Product> products ) {
this.id = id;
this.name = name;
this.products = ofNullable( products ).map( EnumSet::copyOf ).orElse( null );
}
}
I have made a method which creates some dummy data...
public static List<Shop> getListOfShops() {
Shop shop1 = new Shop( 1, "Green Grocer", EnumSet.of( Product.APPLE, Product.BANANA, Product.CARROT, Product.CABBAGE ) );
Shop shop2 = new Shop( 2, "Supermarket", EnumSet.of( Product.APPLE, Product.BANANA
, Product.CARROT, Product.CABBAGE, Product.CHOP, Product.MINCE ) );
Shop shop3 = new Shop( 3, "Butcher", EnumSet.of( Product.STEAK ) );
return Arrays.asList( shop1, shop2, shop3 );
}
I want to create a map of shop categories
Map<String, EnumSet<Category>> shopCategories = new HashMap<>();
which will have contents like this
{Butcher=[MEAT], Supermarket=[FRUIT, VEGITABLE, MEAT], Green Grocer=[FRUIT, VEGITABLE]}
I have achieved this with some basic loops which I was hoping I was smart enough to convert into streams
public static Map<String, EnumSet<Category>> getCategories( List<Shop> shops ) {
Map<String, EnumSet<Category>> shopCategories = new HashMap<>();
for ( Shop s : shops ) {
Set<Category> cats = new HashSet<Category>();
for ( Product p : s.getProducts() ) {
cats.add( p.getCategory() );
}
shopCategories.put ( s.getName(), EnumSet.copyOf (cats) );
}
return shopCategories;
}
I have a vague idea how to convert it to a map of shop to products with a collector as the terminal operation. Something along the lines of
shops.stream().collect( Collectors.toMap ( s -> s::getName ,
PaymentProductWithCapabilities::getProducts ) );
I'm struggling for an entry point into understanding how to proceed to mapping the Categories instead ? Can anyone point me in the right direction ?