user1990218
user1990218

Reputation: 351

Java 8 Mapping a list of maps grouping by a key

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

Answers (1)

fps
fps

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

Related Questions