My class has two fields:
MyKey
- the key that I want to group bySet<MyEnum>
- the set that I want to be flattened and merged.
I have a list of such objects, and what I want is to obtain a Map<MyKey, Set<MyEnum>
of which the value is joined from all myEnums of the objects with this key.
For example, if I have three objects:
myKey: key1, myEnums: [E1]
myKey: key1, myEnums: [E2]
myKey: key2, myEnums: [E1, E3]
The expected result should be:
key1 => [E1, E2], key2 => [E1, E3]
I came up with this code:
Map<MyKey, Set<MyEnum>> map = myObjs.stream()
.collect(Collectors.groupingBy(
MyType::getMyKey,
Collectors.reducing(
new HashSet<MyEnum>(),
MyType::getMyEnums,
(a, b) -> {
a.addAll(b);
return a;
})));
There're two problems with it:
The
HashSet
inside the reducing seems to be shared between all keys. That being said the actual run result of the above example iskey1 => [E1, E2, E3], key2 => [E1, E2, E3]
. Why is it the case?Even if this code works, it looks ugly especially at the part of reducing that I have to handle the logic of constructing the joined collection manually. Is there a better way of doing this?
Thank you!