Reputation: 484
I have a Map<String, List<String>>
and I need to transform it to Map<String, List<Map<String, String>>>
using lambda. Using a normal for loop this problem is trivial but I want to tackle it using java8 lambdas.
The categoryToSubCat
is of type <String, List<String>>
.
Using for loops this is the transformation:
final Map < String, List < Map < String, String >>> transformedMap = new HashMap < > ();
for (Map.Entry < String, List < String >> entry: categoryToSubCat.entrySet()) {
final List < Map < String, String >> subCats = new ArrayList < > ();
for (String subCat: entry.getValue()) {
final Map < String, String > data = new HashMap < > ();
data.put("text", subCat);
data.put("value", subCat);
subCats.add(data);
}
transformedMap.put(entry.getKey(), subCats);
}
The initial map contains data like:
{
"CAT1": [
"CAT1-A",
"CAT1-B"
],
"CAT2": [
"CAT2-A",
"CAT2-B",
"CAT2-C"
]
}
After the transformation it should become something like
{
"CAT1": [
{
"text": "CAT1-A",
"value": "CAT1-A"
},
{
"text": "CAT1-B",
"value": "CAT1-B"
}
],
"CAT2": [
{
"text": "CAT2-A",
"value": "CAT2-A"
},
{
"text": "CAT2-B",
"value": "CAT2-B"
},
{
"text": "CAT2-C",
"value": "CAT2-C"
}
]
}
This does not seem like a problem which cannot be solved using lambdas but I'm just able to get how to do about it.
Please suggest a better approach than the for loop.
Upvotes: 1
Views: 121
Reputation: 1
Here is a lambda version code.
Map<String, List<Map<String, String>>> transformedMap = categoryToSubCat.keySet()
.stream()
.collect(Collectors.toMap(
//keyMapper
key -> key,
//valueMapper
key -> categoryToSubCat.get(key).stream().map(listStr -> {
Map<String, String> map= new HashMap<>();
map.put("text", listStr);
map.put("value", listStr);
return map;
}
).collect(Collectors.toList())
));
or
Map<String, List<Map<String, String>>> transformedMap = categoryToSubCat.entrySet()
.stream()
.collect(Collectors.toMap(
//keyMapper
Map.Entry::getKey,
//valueMapper
entrySet -> entrySet.getValue().stream().map(listStr -> {
Map<String, String> map= new HashMap<>();
map.put("text", listStr);
map.put("value", listStr);
return map;
}
).collect(Collectors.toList())
));
Upvotes: 0
Reputation: 31878
Though an ideal suggestion would be to not use such a data structure, yet if you were to transform the given input, you could try something like:
Map<String, List<Map<String, String>>> transformedMap = categoryToSubCat.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> entry.getValue()
.stream()
.map(subCat -> Map.of("text", subCat, "value", subCat))
.collect(Collectors.toList()), (a, b) -> b));
Upvotes: 1