[英]Java8: How to Convert Map<X, List<Y>> to Map<Y,X> using Stream?
I am new to Java8. 我是Java8的新手。 A problem that I want to solve is to convert Map> to Map using Stream.
我想解决的一个问题是使用Stream将Map>转换为Map。 For example:
例如:
input: {A => [B, C, D], E => [F]}
output: {B => A, C => A, D => A, F => E}
Let's assume that there is no duplicated value in List. 我们假设List中没有重复的值。 How to do it in java 8 stream in an elegant way?
如何在java 8流中以优雅的方式做到这一点?
Cheers, Wei 干杯,魏
If you want a solution without forEach()
you can do: 如果你想要一个没有
forEach()
的解决方案,你可以这样做:
Map<Integer, String> pam =
map.entrySet().stream()
.flatMap(x -> x.getValue().stream().map(v -> new AbstractMap.SimpleEntry<>(v, x.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
For each Entry like "3"-> [3,4,5,6]
a Stream of Entries like 3->3,4->3,5->3,6->3
is created, using flatMap
it can be flattened to one stream, then Collectors.toMap()
creates the final Map
. 对于每个条目,如
"3"-> [3,4,5,6]
一个条目流,如3->3,4->3,5->3,6->3
,使用flatMap
它可以是展平为一个流,然后Collectors.toMap()
创建最终的Map
。
It's really reasy using the free StreamEx library written by me: 使用我编写的免费StreamEx库真的很难过:
EntryStream.of(map).invert().flatMapKeys(Collection::stream).toMap();
Here EntryStream.of(map)
creates a stream of map entries which is extended by additional operations; 这里的
EntryStream.of(map)
创建了一个映射条目流,它通过附加操作进行扩展; invert()
swaps keys and values, flatMapKeys()
flattens keys leaving values unchanged and toMap()
collects the resulting entries back to map. invert()
交换键和值, flatMapKeys()
平键,保持值不变, toMap()
将结果条目收集回map。
Assuming 假设
Map<String, List<Integer>> map = new HashMap<>();
Map<Integer,String> pam = new HashMap<>();
This will do what you want 这将做你想要的
map.entrySet().stream().forEach(e -> e.getValue().stream().forEach(v -> pam.put(v, e.getKey())));
This takes advantage of the fact that Set<E>
implements stream()
from Collection
. 这利用了
Set<E>
从Collection
实现stream()
的事实。 The rest is just plugging things into the right place. 其余的只是把东西塞进正确的地方。
Or, as suggested by @user140547 (thank you), an even simpler solution 或者,正如@ user140547(谢谢)所建议的那样,一个更简单的解决方案
map.forEach((k,v) -> v.forEach(vv -> pam.put(vv, k)));
正如@JimGarrison使用Map.forEach所指出的那样容易得多
input.forEach( (key,value)-> value.forEach(vvalue -> output.put(vvalue, key)));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.