【问题标题】:Get list of duplicate map keys from multiple maps [duplicate]从多个地图中获取重复地图键的列表[重复]
【发布时间】:2020-12-16 06:55:22
【问题描述】:

我有多个数组映射。

Map<String, List<String>> map1 = new HashMap<>();
Map<String, List<String>> map2 = new HashMap<>();
Map<String, List<String>> map3 = new HashMap<>();
Map<String, List<String>> map4 = new HashMap<>();

我想从多个地图中获取重复地图键的列表。

例如

map1.put("k0", Arrays.asList("a0", "a1"));
map1.put("k1", Arrays.asList("b0", "b1"));

map2.put("k1", Arrays.asList("z1", "z2"));
map2.put("k2", Arrays.asList("z1", "z2"));

map3.put("k1", Arrays.asList("z1", "z2"));
map3.put("k3", Arrays.asList("z1", "z2"));

map4.put("k3", Arrays.asList("z1", "z2"));
map4.put("k4", Arrays.asList("z1", "z2"));

map5.put("k0", Arrays.asList("z1", "z2"));
map5.put("k5", Arrays.asList("z1", "z2"));

// Expected output is 
List: [k0, k1, k3]

除了遍历所有映射键,检查集合是否包含键,如果不将键添加到集合中,我想不出任何更简洁的方法来做到这一点。有没有办法通过流来实现这一点?

【问题讨论】:

  • 您不需要检查 Set 是否包含键,因为 Set 项目是唯一的。只需迭代抛出所有键,将它们添加到集合中并使用结果。

标签: java java-stream


【解决方案1】:
@SafeVarargs
private static Set<String> findDuplicateKeys(Map<String, ?>... maps) {
    Set<String> keys = new HashSet<>();
    return Arrays.stream(maps)
            .flatMap(map -> map.keySet().stream())
            .filter(key -> !keys.add(key))
            .collect(Collectors.toSet());
}

我会将结果建模为一个集合而不是列表,因为不可能有重复的元素。

【讨论】:

    【解决方案2】:

    因为你使用的是java-stream标签,你可以这样解决你的问题:

    Set<String> duplicateKeys = Stream.of(map1.keySet(), map2.keySet(), map3.keySet(), map4.keySet(), map5.keySet())
            .flatMap(Set::stream)
            .collect(Collectors.toMap(Function.identity(), x -> false, (a, b) -> true))
            .entrySet().stream()
            .filter(Map.Entry::getValue)
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());
    

    输出

    [k0, k1, k3]
    

    .collect(Collectors.toMap(Function.identity(), x -&gt; false, (a, b) -&gt; true)) 这返回一个 Map&lt;String, Boolean&gt; 它返回密钥和 true 如果重复,false 如果不是,那么您只需过滤以仅获取值为 true 的条目 .filter(Map.Entry::getValue) 表示重复那些。

    【讨论】:

    • 哇,谢谢。你能解释一下这是如何工作的,尤其是“Collectors.toMap(Function.identity(), x -> false, (a, b) -> true)”?
    • @villabilla 是的,将其作为地图收集是一个技巧,在值部分,您只需使用 true 表示重复,使用 false 表示不重复
    • 您能否解释一下以下部分的工作原理(技术上)Collectors.toMap(Function.identity(), x -> false, (a, b) -> true)
    • @PanagiotisBougioukos x -&gt; false 表示如果存在唯一元素则返回 false,(a, b) -&gt; true 表示如果 a 和 b 相等,则表示存在重复,因此返回 true,了解更多详情 @987654321 @
    【解决方案3】:

    或者,你可以试试这个。创建映射流,然后flatMap 将其转换为键流,然后将键收集到 Map 中,计算每个键的数量,然后流式传输 EntrySet,Set&lt;Map.Entry&gt;,按计数进行过滤键的出现,将其映射到键值并收集到列表。这应该可以使用.parallel() 运行。

     private List<String> findDups(Map<String, ?>... maps) {
     return Arrays.asList(maps).stream()
      .flatMap(m->m.keySet().stream())
      .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
      .entrySet().stream()
      .filter(es->es.getValue() > 1)
      .map(es->es.getKey())
      .collect(Collectors.toList());
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-20
      • 2013-04-18
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      相关资源
      最近更新 更多