比较两个地图并删除具有相同键或相同值的所有元素

时间:2016-03-08 09:53:03

标签: java merge hashmap unique

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

基本上,我说有两张地图:

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中执行此操作的最佳方法是什么?

3 个答案:

答案 0 :(得分: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);
    }
}

希望这很有用!

答案 1 :(得分:1)

下面的代码将执行此操作

    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}

答案 2 :(得分:0)

有趣的问题。我无法想到一个特别简洁的方法,但这是一个使用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));