Java: removeIf 2个字段的分组之和等于0

Java: removeIf sum of grouping of 2 fields equals 0

我有一个物品清单。每个项目都有 3 个属性:名称、部分和数量。数量可以是positive/negative。同一项目可以在同一部分多次。

我想按部分和名称对列表中的项目进行分组。如果此分组的总和等于 0 - 删除具有此部分和名称的所有项目。

我走到这一步

items.stream().collect(Collectors.groupingBy(ItemData::getSection))....

现在我需要第二个分组并将其与 0 进行比较,以便将其作为谓词添加到 removeIf

items.removeIf(item -> predicate(item));

您可以先根据 sectionnameItemData 进行分组,并将 amount 的总和作为值

   Map<String,Long> result = details.stream()
            .collect(Collectors.groupingBy(det -> det.getSection()+"_"+det.getName(),
                    Collectors.summingLong(det->det.getAmount())));

然后从 Map 中删除值为 !=0

的条目
   result.entrySet().removeIf(det->det.getValue() != 0);

然后使用键比较

items列表中删除在Map中有条目的元素
items.removeIf(item -> result.containsKey(item.getSection()+"_"+item.getName()));

您还可以使用流

消除值为 0 的条目
Map<String,Long> result = details.stream()
            .collect(Collectors.groupingBy(det -> det.getSection()+"_"+det.getName(),
                    Collectors.summingLong(det->det.getCount())))
           .entrySet()
           .stream()
           .filter(entry->entry.getValue()==0)
           .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));

或者您可以使用 BiPredicate 接受 ItemList<Item>

BiPredicate<Item,List<Item>> biPred = 
    (item, list) -> list.stream()
                        .filter(i -> i.getName().equals(item.getName()) && 
                                     i.getSection().equals(item.getSection()))
                        .mapToLong(Item::getAmount)
                        .sum() == 0;

myList.removeIf(e -> biPred.test(e, myList));