我有3张地图,它们的设置如下:-
//Map1
Map<CatalogCd, Set<ItemUID>> availableItems
//Map2
Map<CatalogCd, FilteringPreferences> filteringPrefs
//Map3
Map<ItemUID, ItemInformation> itemDetailInformation
我想做的是,
仔细检查availableItems,然后查看给定ItemUID的ItemInformation是否与首选项匹配(基本上通过某种谓词检查)。
如您所见,前两个映射具有相同的键,同一键的filterPrefs应用于该目录cd键的整个集合,所有不符合Preferences中谓词设置条件的对象都应从生成的itemuid的集合。
我有兴趣使用Java 8流,映射,过滤器方法使外观看起来更好,而不是传统的循环遍历一个映射,然后手动删除项目或将其添加到新结果映射中。
这是我得到的传统的for循环非java-8样式的代码。
public Map<CatalogCd, Set<ItemUID>> filterResponse(Map<CatalogCd, Set<ItemUID>> availableItems, Map<CatalogCd, FilteringPreferences> filteringPrefs, Map<ItemUID, ItemInformation> itemDetailInformation)
{
Map<CatalogCd, Set<ItemUID>> resultingFilteredItemsMap = new HashMap<>();
for(Map.Entry<CatalogCd,FilteringPreferences> catalogCdEntry : filteringPrefs.entrySet()){
CatalogCd catalogCdInRequest = catalogCdEntry.getKey();
EnumSet<PrefA> prefA = catalogCdEntry.getValue().getSupportedPrefAs();
//get set of items for this catalogcd, loop over each itemuid, check from itemDetailInformation map
//to see if that itemuid's enumset has intersection with the enumset in request's preference.
Set<ItemUID> itemsForThisCatalogCd = availableItems.get(catalogCdInRequest);
for(ItemUID item:itemsForThisCatalogCd){
EnumSet<PrefA> enumSetFromItemInfo = itemDetailInformation.get(item).getPrefAs();
enumSetFromItemInfo.retainAll(prefA);
if(!enumSetFromItemInfo.isEmpty()){
if(resultingFilteredItemsMap.get(catalogCdInRequest)!=null){
Set<ItemUID> items = resultingFilteredItemsMap.get(catalogCdInRequest);
items.add(item);
resultingFilteredItemsMap.put(catalogCdInRequest, items);
}else{
resultingFilteredItemsMap.put(catalogCdInRequest, Sets.newHashSet(item));
}
}
}
}
return resultingFilteredItemsMap;
}
到目前为止,我尝试过的是:-
availableItems
.entrySet()
.stream()
.filter(x- >predicateFilterFactory.createPredicateFilter(filteringPref.get(x.getKey())))
.collect(Collectors.toMap(x->x.getKey(),x->x.getValue));
但是这表示谓词不能转换为布尔值另外,我不知道如何将实际的内容映射到其中。 任何帮助都会很棒。 谢谢
答案 0 :(得分:1)
您在这里:
public Map<CatalogCd, Set<ItemUID>> filterResponse(Map<CatalogCd, Set<ItemUID>> availableItems,
Map<CatalogCd, FilteringPreferences> filteringPrefs, Map<ItemUID, ItemInformation> itemDetailInformation) {
Map<CatalogCd, Set<ItemUID>> resultingFilteredItemsMap = new HashMap<>();
filteringPrefs.forEach((key, value) -> giveSuitableName(availableItems, itemDetailInformation,
resultingFilteredItemsMap, key, value));
return resultingFilteredItemsMap;
}
private void giveSuitableName(Map<CatalogCd, Set<ItemUID>> availableItems,
Map<ItemUID, ItemInformation> itemDetailInformation, Map<CatalogCd, Set<ItemUID>> resultingFilteredItemsMap,
CatalogCd catalogCdInRequest, FilteringPreferences filteringPreferences) {
EnumSet<PrefA> prefA = filteringPreferences.getSupportedPrefAs();
// get set of items for this catalogcd, loop over each itemuid, check from
// itemDetailInformation map
// to see if that itemuid's enumset has intersection with the enumset in
// request's preference.
availableItems.get(catalogCdInRequest).stream()
.map(ai -> collectAndAddItems(itemDetailInformation, resultingFilteredItemsMap, catalogCdInRequest,
prefA, ai))
.filter(s -> !s.isEmpty()).forEach(fs -> resultingFilteredItemsMap.put(catalogCdInRequest, fs));
}
private Set<ItemUID> collectAndAddItems(Map<ItemUID, ItemInformation> itemDetailInformation,
Map<CatalogCd, Set<ItemUID>> resultingFilteredItemsMap, CatalogCd catalogCdInRequest, EnumSet<PrefA> prefA,
ItemUID item) {
EnumSet<PrefA> enumSetFromItemInfo = itemDetailInformation.get(item).getPrefAs();
enumSetFromItemInfo.retainAll(prefA);
Set<ItemUID> items = new HashSet<>();
if (!enumSetFromItemInfo.isEmpty()) {
if (resultingFilteredItemsMap.get(catalogCdInRequest) != null) {
items = resultingFilteredItemsMap.get(catalogCdInRequest);
items.add(item);
} else {
items = new HashSet<>(Arrays.asList(item));
}
}
return items;
}
答案 1 :(得分:1)
此方法应该可以解决您的问题:
public static Map<CatalogCd, Set<ItemUID>> filterResponse(Map<CatalogCd, Set<ItemUID>> availableItems,
Map<CatalogCd, FilteringPreferences> filteringPrefs, Map<ItemUID, ItemInformation> itemDetailInformation) {
return filteringPrefs.entrySet().stream()
.flatMap(e -> availableItems.getOrDefault(e.getKey(), Collections.emptySet())
.stream().map(item -> new AbstractMap.SimpleEntry<>(e, item)))
.filter(e -> itemDetailInformation.get(e.getValue()).getPrefAs().stream()
.anyMatch(e.getKey().getValue().getSupportedPrefAs()::contains))
.collect(Collectors.groupingBy(e -> e.getKey().getKey(), Collectors.mapping(Map.Entry::getValue, Collectors.toSet())));
}
但是我认为这不会使您的代码更具可读性。希望这会有所帮助。