使用flatmap的流分组(groupingBy)

5

我有一个 List<ServiceName> servicesNames,而 ServiceName 具有以下结构:

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

这里的 names 是一个哈希表,包含语言和名称 - 通常有多个值。

我正在尝试获取 Map<String lang, List<String> names>> - 其中键是语言,值是从 List<ServiceName> 中给定语言的所有名称的列表。

到目前为止,这是我得出的结果,但无法将其组合在一起 - 会出现编译错误:

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

编辑: 我能够得到这个:

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

但是不知道如何在使用flatmap后按键分组所有值...


1
如果您实际上发布了编译错误,那会有所帮助。如果我没记错的话,您需要使用groupingBy(Entry::getKey) - daniu
添加了编辑,到目前为止我得到的编译错误实际上是没有意义的,有很多泛型和杂项。 - doublemc
请包含错误信息,否则很难确定错误出现在方法链的哪个位置。如果难以理解,请创建一个适当的 [mcve],使用不同的代码更好地演示问题。 - Zabuzard
1个回答

11
你需要使用Collectors.groupingBy方法来按键分组并通过Collectors.mapping方法对下游数据进行映射。使用基于 lambda 表达式的方法:
Map<String, List<String>> map = servicesNames
        .stream()
        .flatMap(service -> service.getNames().entrySet().stream())
        .collect(groupingBy(e -> e.getKey(), mapping(e -> e.getValue(), toList())));

基于方法引用的方法:

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())));

2
我可以建议展示两个版本,一个只使用方法引用,另一个只使用lambda,而不是部分使用文本来说明。只使用lambda的版本将把mapflatmap合并为一个单独的flatmap,而只使用方法引用的版本将把flatmap拆分为一个map和一个flatmap - Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接