[英]How do I transform a Map<K,V1> to another Map<K,V2> using a map of functions in Java 8?
[英]How do you invert Map<v1, Set<v2>> to Map<v2, Set<v1>> in Java with stream()
我有一個Map對象Map<t1, Set<t2>>
,我想進入集合並將集合中的t2
轉換為新地圖的鍵。 原始鍵t1
將是地圖的新值。
例如,給定一個包含兩個條目的地圖
{key1: [a, b, c], key2: [c, d]}
得到的地圖將是
{a: [key1], b: [key1], c: [key1, key2], d: [key2]}
[]表示在上面的例子中設置。
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())
StreamEx :
EntryStream.of(map)
.flatMapValues(Set::stream)
.invert()
.grouping(Collectors.toSet())
一種方法可能是:
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;
}
一種方法可以是 -
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);
}});
}
}));
使用流(可能適合在流上使用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)));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.