Reputation: 351
I have the following: List<Map<String, Object>>
. I want to obtain a Map<String, List<Object>
using streams. The key of this map will be the key, that it is repeated in the list. Basically, is a one-to-many, this would be an example of the data:
[
{ id: "a", name: "AAA"}
{ id: "a", name: "BBB"}
{ id: "b", name: "XXX"}
{ id: "b", name: "YYY"}
]
And I would like to obtain:
{
a: ["AAA", "BBB"],
b: ["XXX", "YYY"]
}
So, this new map is grouping by id from the previous list.
Upvotes: 2
Views: 14864
Reputation: 34450
Use Collectors.groupingBy
along with Collectors.mapping
:
Map<String, List<Object>> result = listOfMaps.stream()
.collect(Collectors.groupingBy(map -> map.get("id").toString(),
Collectors.mapping(map -> map.get("name"),
Collectors.toList())));
Collectors.groupingBy
creates the map you want, while Collectors.mapping
adapts a collector into another one by applying a mapping function to each element of the stream. (In this case, it collects to a list by first transforming each map of the stream to the value mapped to the "name"
key).
If needed, the code above might be modified to skip maps that don't have an entry with the "id"
key:
Map<String, List<Object>> result = listOfMaps.stream()
.filter(map -> map.get("id") != null))
.collect(Collectors.groupingBy(map -> map.get("id").toString(),
Collectors.mapping(map -> map.get("name"),
Collectors.toList())));
Upvotes: 4