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.
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()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With