从Map <k,collection <v>&gt;创建Multimap键为V [0],值为K,使用Java 8

时间:2015-06-04 15:51:13

标签: java-8 guava

我有Map<String,List<String>>(比如inputMap),我想把它转换成另一个Map<String,List<String>>,其中新地图中的每个(k,v)是(v.get(0),k) inputMap。

实施例

X -> B,C,D
Y -> B,D,E
Z -> B,G,H
P -> A,B,D
Q -> A,D,F
R -> A,C,B

B->X,Y,Z
A->P,Q,R

我最初认为我可以使用像

这样的东西
inputMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue.get(0),Map.Entry::getKey));

然后将此地图转换为多地图,但我无法编写Map.Entry::getValue.get(0)

如果我可以在.collect()本身创建多图,那也很棒。

3 个答案:

答案 0 :(得分:3)

这是一种方法:

Map<String, List<String>> output = input.entrySet().stream()
        //create new entries mapping B to X, B to Y, B to Z etc.
        .map(e -> new SimpleEntry<>(e.getValue().get(0), e.getKey()))
        //we group by the key (B or A) and we collect the values into a list
        .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList())));

答案 1 :(得分:1)

方法引用不起作用。如果您不能将函数表达为方法的引用,则需要lambda表达式。

此外,如果您需要多个值,toMap收集器不是最佳选择,groupingBy是正确的工具。

Map<String,List<String>> result=map.entrySet().stream().collect(
    Collectors.groupingBy(e->e.getValue().get(0),
        Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

答案 2 :(得分:0)

您可以直接收集到Multimap

Multimap<String, String> result = inputMap.entrySet().stream()
        .collect(
                ArrayListMultimap::create,
                (mm,e) -> mm.put(e.getValue().get(0), e.getKey()),
                Multimap::putAll
        );