I’m using Java8 Streams to iterate through a list and for each of the element I invoke map
and then I need to aggregate the results. My problem is that when I call groupingBy
I also need to access the original object before calling map
. Here is a snippet:
list.stream() // .filter(item -> item.getType() == HUMAN) // .map(item -> manager.itemToHuman(item.getId())) // .filter(Objects::nonNull) // .collect(Collectors.groupingBy(Human::getAge, Collectors.summarizingLong(item.getCount())));
The problem is with the call to Collectors.summarizingLong(item.getCount())
since item
at this point is NOT accessible. Is there an elegant way to overcome this?
Advertisement
Answer
After doing map()
stream transformed into Stream<Human>
so you can’t use item
object in the collector.
You can transform item
into a pair of Human
object and count
using SimpleEntry
then use it on the collector.
list.stream() .filter(item -> item.getType() == HUMAN) .map(item -> new AbstractMap.SimpleEntry<>(manager.itemToHuman(item.getId()), item.getCount())) .filter(entry -> Objects.nonNull(entry.getKey())) .collect(Collectors.groupingBy(entry -> entry.getKey().getAge(), Collectors.summarizingLong(Map.Entry::getValue)));