英文:
java 8 stream groupingBy into collection of custom object
问题
以下是翻译好的内容:
我有以下的类结构
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;
}
}
我想将 "List
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));
英文:
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>". 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));
答案1
得分: 2
以下是翻译后的内容:
由于在组中masterStoreId
和operatorIdentifier
相同(在注释中确认),您可以使用AbstractMap.SimpleEntry
创建它们的配对,然后使用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())));
英文:
As masterStoreId
and operatorIdentifier
are same same in group(comfirmed in comment) you can groupingBy both creating pair of them using AbstractMap.SimpleEntry
. Then using Collectors.toMap
create map.
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())));
答案2
得分: 1
为了完成这个实现,您正在尝试的部分需要确保在 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);
}
这将简化收集器的实现,并且您可以相应地调用它们:
Map<Long, StoreInfo> storeInfoAgainstMasterStore = stores.stream()
.collect(Collectors.toMap(Store::getMasterStoreId,
store -> new StoreInfo(store.getOperatorIdentifier(), store.getStoreId()),
StoreInfo::mergeStoreInfo));
英文:
To complete the implementation, you were attempting. You need to ensure merging capability within StoreInfo
such as :
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));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论