Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java streams map class property list to flattened map

How can we turn a List<Foo> towards a Map<propertyA, List<propertyB>> in the most optimal way by using java streams.

Beware: propertyA is NOT unique

//pseudo-code
class Foo
    propertyA //not unique
    List<propertyB>

So far I have the following:

fooList.stream()
       .collect(Collectors.groupingBy(Foo::propertyA, 
                    Collectors.mapping(Foo::propertyB, Collectors.toList())))

Resulting into a Map<propretyA, List<List<propretyB>>> which is not yet flattened for its value.

like image 661
Terence Avatar asked Apr 08 '26 17:04

Terence


1 Answers

You could use Java 9+ Collectors.flatMapping:

Map<propretyA, List<propretyB>> result = fooList.stream()
       .collect(Collectors.groupingBy(Foo::propertyA, 
                Collectors.flatMapping(foo -> foo.propertyB().stream(), 
                                       Collectors.toList())));

Another way (Java8+) is by using Collectors.toMap as in this answer.

And yet another Java8+ way is to just not use streams, but use Map.computeIfAbsent instead:

Map<propretyA, List<propretyB>> result = new LinkedHashMap<>();
fooList.forEach(foo -> result.computeIfAbsent(foo.propertyA(), k -> new ArrayList<>())
                             .addAll(foo.propertyB()));
like image 108
fps Avatar answered Apr 11 '26 07:04

fps



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!