I'm trying to convert a List into a Map of Objects where that Objects holds the List.
Consider the following classes:
class A {
String code;
}
class B {
A a;
String value;
}
AB {
A a;
List<B> bList;
}
I have a List<B> sourceList
that I want to convert into a Map<String, AB> targetMap
If we have the following data for sourceList:
[
{
value = "foo",
a = {code = "code1"}
},
{
value = "bar"
a = {code = "code1"}
{
value = "hello"
a = {code = "code2"}
}
]
The targetMap should look like this:
{
"code1" =
{
a = {code = "code1"}
bList =
[
{
value = "foo",
a = {code = "code1"}
},
{
value = "bar",
a = {code = "code1"}
}
]
},
"code2" =
{
a = {code = "code2"}
bList =
[
{
value = "hello"
a = {code = "code2"}
}
]
}
}
How can I do this?
I tried using the Collectors.groupingBy
and Collectors.mapping
but both looks like only results in a Map of a Collection.
Use groupingBy
to group by getA().getCode()
as usual. In the downstream, use Collectors.toList
, similar to what the one-argument groupingBy
collector does, but then, convert that List<B>
into an AB
using collectingAndThen
.
Map<String, AB> convert(List<B> list) {
return list.stream().collect(Collectors.groupingBy(
x -> x.getA().getCode(),
Collectors.collectingAndThen(
Collectors.toList(),
// assuming AB has a constructor that takes an A and a List<B>
bs -> new AB(bs.get(0).getA(), bs)
)
));
}
Since groupingBy
does not create empty groups, bs
is always non-empty, so it is safe to do bs.get(0)
.