【问题标题】:How to create a reverse map when original map contains collection as the value?当原始地图包含集合作为值时如何创建反向地图?
【发布时间】:2019-02-15 07:17:56
【问题描述】:

假设我原来的Map 包含以下内容:

Map<String, Set<String>> original = Maps.newHashMap();
original.put("Scott", Sets.newHashSet("Apple", "Pear", "Banana");
original.put("Jack", Sets.newHashSet("Banana", "Apple", "Orange");

我想创建一个反向的Map,其中包含以下内容:

  "Apple":  ["Scott", "Jack"]
  "Pear":   ["Scott"]
  "Banana": ["Scott", "Jack"]
  "Orange": ["Jack"]

我知道它可以以旧方式(Java 8 之前)完成,但是如何使用 Java Stream API 实现相同的功能?

Map<String, Set<String>> reversed = original.entrySet().stream().map(x -> ????).collect(??)

here 发布了类似的问题,但这仅适用于单值 Maps。

【问题讨论】:

  • 您是否考虑过谷​​歌搜索:java 流反向排序?此外,它闻起来像家庭作业o.O

标签: java java-8 java-stream


【解决方案1】:

您可以使用flatMapMap 分解为键值对(其中每个键和值都是一个String),然后根据需要收集它们:

Map<String,Set<String>> rev =
    original.entrySet ()
            .stream ()
            .flatMap (e -> e.getValue ()
                            .stream ()
                            .map (v -> new SimpleEntry<String,String>(v,e.getKey ())))
            .collect(Collectors.groupingBy (Map.Entry::getKey,
                                            Collectors.mapping (Map.Entry::getValue, 
                                                                Collectors.toSet())));
System.out.println (rev);

输出:

{Apple=[Jack, Scott], Pear=[Scott], Orange=[Jack], Banana=[Jack, Scott]}

【讨论】:

  • 感谢您的回答。很高兴知道如何使用纯 Streaming API 来完成。
【解决方案2】:

更重要但更简单的解决方案是使用forEach

Map<String, Set<String>> original,result; // initialised
original.forEach((key, value) -> value.forEach(v -> 
            result.computeIfAbsent(v, k -> new HashSet<>()).add(key)));

【讨论】:

  • 我喜欢这个解决方案的可读性和简单性,所以我采用了这种方法。非常感谢!
  • @nanaboo 欢迎您,如果您的问题得到解决,请不要忘记接受答案。
猜你喜欢
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2021-07-12
  • 1970-01-01
相关资源
最近更新 更多