简体   繁体   English

java 8流分组到自定义对象的集合

[英]java 8 stream groupingBy into collection of custom object

I have the following class structure我有以下类结构


public class Store {
    private Long storeId;

    private Long masterStoreId;

    private String operatorIdentifier;
}

public class StoreInfo {

    private String operatorIdentifier;

    private Set<Long> slaveStoreIds;

    public StoreInfo(String operatorIdentifier, Set<Long> slaveStoreIds) {
        super();
        this.operatorIdentifier = operatorIdentifier;
        this.slaveStoreIds = slaveStoreIds;
    }

}

I want to collect the "List<Store" into a "Map<Long, StoreInfo>".我想将“List<Store”收集到“Map<Long, StoreInfo>”中。 Is it possible to do so in a single operation/iteration?是否可以在单个操作/迭代中这样做?

List<Store> stores;

Map<Long, Set<Long>> slaveStoresAgainstMasterStore = stores.stream().collect(Collectors
                .groupingBy(Store::getMasterStoreId, Collectors.mapping(Store::getStoreId, Collectors.toSet())));

Map<Long, StoreInfo> storeInfoAgainstMasterStore = stores.stream()
                .collect(
                        Collectors
                                .toMap(Store::getMasterStoreId,
                                        val -> new StoreInfo(val.getOperatorIdentifier(),
                                                slaveStoresAgainstMasterStore.get(val.getMasterStoreId())),
                                        (a1, a2) -> a1));


As masterStoreId and operatorIdentifier are same same in group(comfirmed in comment) you can groupingBy both creating pair of them using AbstractMap.SimpleEntry .由于masterStoreIdoperatorIdentifier在组中相同(在评论中确认),您可以 groupingBy 使用AbstractMap.SimpleEntry创建它们对。 Then using Collectors.toMap create map.然后使用Collectors.toMap创建地图。

Map<Long, StoreInfo> storeInfoMap = 
    stores.stream()
          .collect(Collectors.groupingBy(
                      e -> new AbstractMap.SimpleEntry<>(e.getMasterStoreId(),
                                                        e.getOperatorIdentifier()),
                      Collectors.mapping(Store::getStoreId, Collectors.toSet())))
          .entrySet()
          .stream()
          .collect(Collectors.toMap(e -> e.getKey().getKey(),
                            e -> new StoreInfo(e.getKey().getValue(), e.getValue())));

To complete the implementation, you were attempting.为了完成实施,您正在尝试。 You need to ensure merging capability within StoreInfo such as :您需要确保StoreInfo合并功能,例如:

public StoreInfo(String operatorIdentifier, Long slaveStoreId) {
    this.operatorIdentifier = operatorIdentifier;
    this.slaveStoreIds = new HashSet<>();
    this.slaveStoreIds.add(slaveStoreId);
}

public static StoreInfo mergeStoreInfo(StoreInfo storeInfo1, StoreInfo storeInfo2) {
    Set<Long> slaveIds = storeInfo1.getSlaveStoreIds();
    slaveIds.addAll(storeInfo2.getSlaveStoreIds());
    return new StoreInfo(storeInfo1.getOperatorIdentifier(), slaveIds);
}

this would simplify the implementation of collector and you an invoke these correspondingly:这将简化收集器的实现,您可以相应地调用这些:

Map<Long, StoreInfo> storeInfoAgainstMasterStore = stores.stream()
        .collect(Collectors.toMap(Store::getMasterStoreId,
                store -> new StoreInfo(store.getOperatorIdentifier(), store.getStoreId()),
                StoreInfo::mergeStoreInfo));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM