Search code examples
javajava-streampredicate

Java: removeIf sum of grouping of 2 fields equals 0


I have a list of items. Each item has 3 properties: name, section and amount. The amount can be positive/negative. The same item can be several times in the same section.

I want to group the items in the list by section and name. If the sum of this grouping equals 0 - remove all the items with this section and name.

I got this far

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

Now I need the second grouping and compare it to 0 in order to add it as a predicate to removeIf

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

Solution

  • You can first group the ItemData based on section and name with sum of amount as value

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

    And then remove the entries from Map having value !=0

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

    And then remove the elements from items list having entry in Map with key comparison

    items.removeIf(item -> result.containsKey(item.getSection()+"_"+item.getName()));
    

    You can also eliminate the entries having value 0 by using stream

    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));