我有一个地图对象Map<t1, Set<t2>>
,我想进入集合并将集合中的t2
转换为新地图的键。原始密钥t1
将是地图的新值
例如,给定一个包含两个条目的地图
{key1: [a, b, c], key2: [c, d]}
生成的地图将是
{a: [key1], b: [key1], c: [key1, key2], d: [key2]}
[]表示在上面的例子中设置。
答案 0 :(得分:8)
Java 8:
map.entrySet()
.stream()
.flatMap(e -> e.getValue()
.stream()
.map(v -> new SimpleEntry<>(v, e.getKey())))
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue, Collectors.toSet())))
Multimaps.asMap(map.entrySet()
.stream()
.collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
Entry::getKey, e -> e.getValue().stream()))
.inverse())
EntryStream.of(map)
.flatMapValues(Set::stream)
.invert()
.grouping(Collectors.toSet())
答案 1 :(得分:1)
一种方法可能是:
private static <T1,T2> Map<T1, Set<T2>> invertMap(Map<T2, Set<T1>> data) {
Map<T1, Set<T2>> output = data.entrySet().stream().collect(() -> new HashMap<T1, Set<T2>>(),
(mapLeft, leftEntry) -> {
for (T1 i : leftEntry.getValue()) {
Set<T2> values = mapLeft.get(i);
if (values == null)
values = new HashSet<>();
values.add(leftEntry.getKey());
mapLeft.put(i, values);
}
}, (mapLeft, mapRight) -> mapLeft.putAll(mapRight));
return output;
}
答案 2 :(得分:0)
一种方法可以是 -
Map<V1,Set<V2>> inputHashMap = new HashMap<>(); // initialized with your input
Map<V2,Set<V1>> outputHashMap = new HashMap<>();
inputHashMap.forEach((val, keys) -> keys.forEach(key -> {
if (outputHashMap.containsKey(key)) {
outputHashMap.get(key).add(val);
} else {
outputHashMap.put(key, new HashSet<>() {{
add(val);
}});
}
}));
答案 3 :(得分:0)
使用流(可能适合在流上使用parallel()
进行并行处理)
Map<String, Set<String>> inMap = new HashMap<>();
inMap.put("key1", new HashSet<>(Arrays.asList("a", "b", "c")));
inMap.put("key2", new HashSet<>(Arrays.asList("c", "d")));
Map<String, Set<String>> outMap = inMap.entrySet().stream().collect(
HashMap::new,
(m, e) -> e.getValue().forEach(v -> m.computeIfAbsent(v, ignore -> new HashSet<>())
.add(e.getKey())),
(m1, m2) -> m2.forEach((key, value) -> m1.merge(key, value,
(s1, s2) -> { s1.addAll(s2); return s1; })));
System.out.println(outMap);
// {a=[key1], b=[key1], c=[key1, key2], d=[key2]}
当然,旧学校for
循环更清洁
Map<String, Set<String>> outMap = new HashMap<>();
for (Entry<String, Set<String>> e : inMap.entrySet())
for (String v : e.getValue())
outMap.computeIfAbsent(v, key -> new HashSet<>()).add(e.getKey());
更少LOC
Map<String, Set<String>> outMap = new HashMap<>();
inMap.forEach((k, v) -> v.forEach(e ->
outMap.computeIfAbsent(e, __ -> new HashSet<>()).add(k)));