作者:白猫警员123 | 来源:互联网 | 2022-11-18 13:58
我正在尝试实现该功能:
private static Map > invertedMap(Map > m)
例如,如果我有Map >
,
我想创造另一个Map >
.
我写了一些代码:
private static Map> invertedMap(Map m) {
return m.keySet().stream()
.collect(Collectors.groupingBy(k -> m.get(k)));
}
但正如您所看到的,只有在参数中的地图不包含列表作为值时,这才有效.
1> Federico Per..:
我不会为此使用流(如果你想要一个基于流的解决方案,请检查 nullpointer的答案):
private static Map> invertedMap(Map> map) {
Map> result = new LinkedHashMap<>(); // Preserves insertion order
map.forEach((k, l) ->
l.forEach(t -> result.computeIfAbsent(t, d -> new ArrayList<>()).add(k)));
return result;
}
上面的代码迭代输入映射map
和每个元件t
其中的每一个的List
值l
,它使用Map.computeIfAbsent
以生成结果.
Map.computeIfAbsent
如果有给定键的条目,则返回该值,或者创建该条目并返回其第二个参数指定的值d -> new ArrayList<>()
(这里d
代表我们不需要的伪参数,以便创建新的空列表).然后,将密钥k
添加到返回的列表中Map.computeIfAbsent
.
2> Naman..:
这是一种流式的方式(虽然我的第一直觉本身就是遵循Federico的解决方案):
private static Map> invertedMapOfList(Map> m) {
return m.entrySet()
.stream()
.flatMap(e -> e.getValue()
.stream()
.map(v -> new AbstractMap.SimpleEntry<>(e.getKey(), v)))
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
}