Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream groupingBy with flatmap

I have List<ServiceName> servicesNames and ServiceName has this structure:

public class ServiceName {
private Map<String, String> names;
}

Where names is a Hashmap with language and name - usually several values.

I'm trying to get Map<String lang, List<String> names>> - where key is language and value is a List of all the names in given language from List<ServiceName>.

Here is what I came by so far but can;t just put it together - getting compilation errors:

servicesNames
    .stream()
    .map(x -> x.getNames())
    .flatMap(x -> x.entrySet().stream())
    .collect(x -> Collectors.groupingBy());

EDIT: I'm able to get this:

List<Map.Entry<String, String>> collect1 = servicesNames
    .stream()
    .map(x -> x.getNames())
    .flatMap(x -> x.entrySet().stream())
    .collect(Collectors.toList());

But don't know to to actually group by key all the values after using flatmap...

like image 894
ohwelppp Avatar asked Dec 24 '22 09:12

ohwelppp


1 Answers

You need Collectors.groupingBy to group the values by a key and apply mapping to the downstream by Collectors.mapping.

The lambda-based approach:

Map<String, List<String>> map = servicesNames
        .stream()
        .flatMap(service -> service.getNames().entrySet().stream())
        .collect(groupingBy(e -> e.getKey(), mapping(e -> e.getValue(), toList())));

The method reference-based approach:

Map<String, List<String>> map = servicesNames
        .stream()
        .map(ServiceName::getNames)
        .map(Map::entrySet)
        .flatMap(Set::stream)
        .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));
like image 66
Andrew Tobilko Avatar answered Jan 09 '23 22:01

Andrew Tobilko