Java 如何收集pojo id到pojo上集合属性集的映射

Java 如何收集pojo id到pojo上集合属性集的映射,java,java-8,java-stream,Java,Java 8,Java Stream,我尝试使用streams来获取pojo到pojo上的属性公开的一组项的映射。我意识到这还不清楚,所以我将展示我在没有流的情况下是如何做到的 我有和产品类别的枚举,产品的枚举和商店的列表 public enum Category { FRUIT, VEGITABLE, MEAT; } public enum Product { APPLE ( Category.FRUIT ), PEAR ( Category.FRUIT ), BANANA ( Category.

我尝试使用streams来获取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 );
    }
}

我正在努力寻找一个切入点来理解如何继续映射类别?有人能给我指出正确的方向吗?

您可以使用
Collectors.toMap中的
valueMapper
将您正在浏览的店铺的产品转换为预期的
Map
,类似于您的迭代风格:

return shops.stream()
        .collect(Collectors.toMap(Shop::getName,
                s -> EnumSet.copyOf(s.getProducts().stream()
                        .map(Product::getCategory)
                        .collect(Collectors.toSet()))));
准确地说,如果在
收集器中找到两个相同的
名称
,则您的实现将覆盖
映射的值。可以使用合并功能(如
(a,b)->b
)来实现toMap

或者更好,如a中所述:


使用
collector.groupingBy
collector.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)))));
地图类别=
商店.溪流()
.收集(
分组依据(
商店::getName,
平面映射(
s->s.getProducts().stream().map(产品::getCategory),
toCollection(()->EnumSet.noneOf(Category.class‘‘‘‘)’);
Collectors.groupingBy
根据
Shop::getName
收集器对流进行分组。flatMapping
展平产品列表,并将产品映射到
产品
类别<代码>收集器。flatMapping也
收集器
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 ) );
return shops.stream()
        .collect(Collectors.toMap(Shop::getName,
                s -> EnumSet.copyOf(s.getProducts().stream()
                        .map(Product::getCategory)
                        .collect(Collectors.toSet()))));
return shops.stream()
        .collect(Collectors.toMap(Shop::getName,
                s -> s.getProducts().stream()
                        .map(Product::getCategory)
                        .collect(Collectors.toCollection(
                                () -> EnumSet.noneOf(Category.class))),
                (a, b) -> b));
Map<String, EnumSet<Category>> categories =
        shops.stream()
            .collect(
                groupingBy(
                    Shop::getName,
                    flatMapping(
                        s -> s.getProducts().stream().map(Product::getCategory),
                        toCollection(() -> EnumSet.noneOf(Category.class)))));