Flat-Mapping Collector for class property using grouping By

I have this class.

class Assignment { private Integer index; private List<Quantity> quantities; } 

Then I have a list of objects from this class.

 List<Assigment> assignments = new ArrayList<>(); 

Is there a way to create a Map that contains an index from Assignment and List<Quantity> as values?

This is what I have tried so far.

 assignments.stream().collect(groupingBy(Assignment::getIndex)); 

But that gives me a Map<Integer, List<Assignment>> , and I want a Map<Integer, List<Quantity>> .

I tried using the forEach method - and it works - but I'm sure there must be a way to do this in one liner - or at least use only the collect and groupingBy methods

+5
source share
1 answer

There seems to be no flat map collector that can be used as a downstream for groupingBy in Java8, but it was proposed and adopted for Java9: https://bugs.openjdk.java.net/browse/JDK-8071600

 public static <T, U, A, R> Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper, Collector<? super U, A, R> downstream) { BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator(); return Collector.of(downstream.supplier(), (r, t) -> mapper.apply(t).sequential().forEach(u -> downstreamAccumulator.accept(r, u)), downstream.combiner(), downstream.finisher(), downstream.characteristics().stream().toArray(Collector.Characteristics[]::new)); } 

If you use this, and also add the quantities method to Assignment , which returns Stream<Quantity> , you can use this code:

 Map<Integer, List<Quantity>> result = assignments.stream() .collect(groupingBy(Assignment::getIndex, flatMapping(Assignment::quantities, toList()))); 
+8
source

Source: https://habr.com/ru/post/1263398/


All Articles