简体   繁体   English

Java8:如何转换地图 <X, List<Y> &gt;到地图 <Y,X> 使用Stream?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM