我正在尝试使用流将pojo的地图映射到由pojo上的属性公开的一组项目。我知道还不清楚,所以我将展示如何在没有流的情况下完成它。
我拥有和列举产品类别,并列出具有此类产品的产品清单和商店清单
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 );
}
}
我已经建立了一种创建一些虚拟数据的方法...
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 );
}
我要创建商店类别地图
Map<String, EnumSet<Category>> shopCategories = new HashMap<>();
将具有这样的内容
{屠夫= [肉类],超市= [水果,蔬菜,肉类],绿色 Grocer = [水果,蔬菜]}
我已经通过一些基本的循环实现了这些,我希望自己足够聪明,可以将其转换为流
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;
}
我有一个模糊的想法,如何将其转换为商店地图,并以收藏家为终端操作的产品。类似于
shops.stream().collect( Collectors.toMap ( s -> s::getName ,
PaymentProductWithCapabilities::getProducts ) );
我正在努力寻找一个切入点,以了解如何继续映射类别?谁能指出我正确的方向?
答案 0 :(得分:3)
您可以使用add_done_callback()
中的Map
,将正在经营的商店的产品转换为期望的valueMapper
的价值,类似于您的迭代风格,如下所示:>
Collectors.toMap
准确地说,如果为两个商店找到了相同的return shops.stream()
.collect(Collectors.toMap(Shop::getName,
s -> EnumSet.copyOf(s.getProducts().stream()
.map(Product::getCategory)
.collect(Collectors.toSet()))));
,则您的实现将覆盖Map
的值,而在name
中可以使用合并功能实现,例如为Collectors.toMap
。
(a,b) -> b
答案 1 :(得分:1)
使用Collectors.groupingBy
和Collectors.flatMapping
作为-
Map<String, EnumSet<Category>> categories =
shops.stream()
.collect(
groupingBy(
Shop::getName,
flatMapping(
s -> s.getProducts().stream().map(Product::getCategory),
toCollection(() -> EnumSet.noneOf(Category.class)))));
Collectors.groupingBy
组流基于Shop::getName
和Collectors.flatMapping
展开产品列表,并且map
将产品映射到Product
类别。 Collectors.flatMapping
也是Collector<? super U, A, R> downstream
,可用于收集EnumSet<Category>
。