【问题标题】:Compare two Maps and remove all the elements that either have the same key or the same value比较两个 Map 并删除所有具有相同键或相同值的元素
【发布时间】:2016-06-22 04:56:09
【问题描述】:

我有两个地图,我需要比较它们并将它们合并到一个结果地图中。我需要删除所有具有相同键或相同值的元素。

基本上,假设我有两个地图:

Map<String, String> map1 = new HashMap<>();
map1.put("1", "A");
map1.put("2", "A");
map1.put("3", "B");
map1.put("4", "C");
map1.put("5", "D");
map1.put("6", "E");

Map<String, String> map2 = new HashMap<>();
map2.put("1", "B");
map2.put("2", "A");
map2.put("4", "F");
map2.put("6", "C");
map2.put("7", "G");
map2.put("8", "H");

我需要删除所有具有相同键或相同值的条目,并且只需要保留双向唯一条目。所以合并后,我需要有以下结果映射,其中每个键映射到一个唯一值,每个值都有一个唯一键:

("5", "D"), ("7", "G"), ("8", "H")

在 Java 中最好的方法是什么?

【问题讨论】:

    标签: java merge hashmap unique


    【解决方案1】:

    我将创建另一个映射,其中包含来自 map1 和 map2 的所有值和键,然后我将通过一个循环删除重复的键和值

    Map<String, String> map3 = new HashMap<>();
    map3.putAll(map1);
    map3.putAll(map2);
    
    for(String a: map1.keySet()){
        if(map2.containsKey(a) || map2.containsValue(map1.get(a))){
            map3.remove(a);
        }
    }
    

    希望这有用!

    【讨论】:

    • 您可能应该遍历 map3 键!
    • 然后我会出现java.util.ConcurrentModificationException 错误,因为我正在从 map3 中删除元素
    • 啊,真的!你也许应该使用带有 .remove() 方法的迭代器.. 但现在我意识到它没关系,就像它一样
    • 谢谢。但如果两张地图颠倒,这个解决方案将不起作用。由于我们在这里迭代了 map1 的键,因此 map2 中的任何键都将保留在 map3 中,即使它们映射到非唯一值。
    【解决方案2】:

    下面的代码会这样做

        Map map3 = new HashMap<>(map1);
        map3.keySet().removeAll(map2.keySet());
        map3.values().removeAll(map2.values());
        map2.keySet().removeAll(map1.keySet());
        map2.values().removeAll(map1.values());     
        map3.putAll(map2);
        System.out.println(map3);
    

    这将导致{7=G, 5=D, 8=H}

    【讨论】:

      【解决方案3】:

      有趣的问题。我想不出一种特别巧妙的方法,但这里有一个使用 Java 8 的潜在解决方案——我很确定它可以稍微简化一些。我不喜欢中间流中的这类有状态操作,但我能看到的唯一避免它的方法是将其拆分为两个操作。

      Set<Map.Entry<String, String>> values = new HashSet<>();
      Map<String,String> mergedMap =
          Stream.concat(map1.entrySet().stream(), map2.entrySet().stream)
          .filter(e -> !values.keySet().contains(e.getKey()))
          .filter(e -> !values.valueSet().contains(e.getValue()))
          .peek(e -> values.add(e))
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
      

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 1970-01-01
        • 2016-03-11
        • 2023-03-17
        • 1970-01-01
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 2014-09-05
        相关资源
        最近更新 更多