Java流按内部数组分组

3
我有以下类的对象列表:

Class:

class Response {
     public String shortName; 
     public String[] types;
}

我希望使用流对类型进行分组操作。 例如,如果我有一个如下所示的Responses列表: [{"阿拉斯加",["州","管理员级别1"]},{"新泽西",["州","管理员级别2"]}] 结果应该是类似于地图的形式:

{"state":["Alaska", "New Jersey"], "admin level1": ["Alaska"], "admin level2": "New Jersey"}

2
你尝试过非流式方式吗? - Thiyagu
1
当你包含自己的努力时,这样的问题会更好地解决...+ - GhostCat
1
我认为对于这种问题,没有其他的选择,要么你懂它,要么你不懂。我尝试过不用 group by 的方式,也能运作,但我想知道 group by 的方法。如果问题特别涉及到 group by,那么没有使用 group by 的发帖是毫无意义的。 - Sagar
这个 [{"Alaska", ["state", "admin level1"]}, {"New Jersey", ["state", "admin level2"]}] 的 JSON 怎么成为响应列表? - GolamMazid Sajib
1个回答

4

map 每个 Response 中的字符串数组为一个 SimpleEntry,然后将其扁平化并应用 groupingBy,其中 mapping 作为下游收集器。

Map<String, List<String>> resultSet = 
      responses.stream()
               .flatMap(e -> Arrays.stream(e.getTypes()).map(a -> new AbstractMap.SimpleEntry<>(a, e.getShortName())))
               .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
                        Collectors.mapping(AbstractMap.SimpleEntry::getValue, 
                                            Collectors.toList())));

如果您希望按照帖子中显示的顺序获取结果,则需要将结果转储到 LinkedHashMap 中:

...
...
.collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
       LinkedHashMap::new, // a supplier providing a new empty map into which the results will be inserted
       Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())));

我认为按照这种顺序将键/值放入条目中有点反常:你正在创建一个以类型为键的映射,因此最好在此处将类型作为键。但实际上并不真的很重要,因为该条目的生命周期非常短暂。 - Andy Turner
@AndyTurner 当然没问题,无论是什么让社区开心,我已经把它们调换了 ;-). - Ousmane D.
@Aomine 我不认为我代表整个社区。这只是一个建议。 - Andy Turner
在方法引用中,您不需要引用AbstractMap.SimpleEntry。只需使用Map.Entry::getKeyMap.Entry::getValue即可。这样可以简化未来的更改,例如当您切换到Java 9或更新版本并将new AbstractMap.SimpleEntry<>(…)替换为Map.entry(…)时。 - Holger

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