在2个HashMaps中查找不同的值

时间:2016-01-28 14:21:12

标签: java hashmap

我有2个拥有数百万条记录的HashMaps。为简单起见,我将只处理几条记录。我想找到地图a中不在地图b中的值。有这个功能吗?什么是最快捷的方式?

Map a = new HashMap();
a.put(1, "big");
a.put(2, "hello");
a.put(3, "world");

Map b = new HashMap();

b.put(1,"hello");
b.put(2, "world");

在这种情况下,输出应为"big",因为它位于a而非b

6 个答案:

答案 0 :(得分:10)

您正在寻找关于地图值的removeAll操作。

public static void main(String[] args) {
    Map<Integer, String> a = new HashMap<>();
    a.put(1, "big");
    a.put(2, "hello");
    a.put(3, "world");

    Map<Integer, String> b = new HashMap<>();
    b.put(1,"hello");
    b.put(2, "world");

    a.values().removeAll(b.values()); // removes all the entries of a that are in b

    System.out.println(a); // prints "{1=big}"
}

values()返回此地图中包含的值的视图:

  

返回此地图中包含的值的Collection视图。该集合由地图支持,因此对地图的更改将反映在集合中,反之亦然。

因此,从值中删除元素会有效地删除条目。这也记录在案:

  

该集合支持元素删除,它通过Iterator.removeCollection.removeremoveAllretainAllclear操作从地图中删除相应的映射

这将从地图中删除。如果您想要一个包含结果的新地图,您应该在新的地图实例上调用该方法。

Map<Integer, String> newMap = new HashMap<>(a);
newMap.values().removeAll(b.values());

旁注:don't use raw types

答案 1 :(得分:2)

@Tunaki的解决方案可以正常工作,可读性和简短。

只是为了完整性解决方案&#34;手工&#34;:

for (String s : a.values()) {
    if (!b.containsValue(s)) {
        System.out.println (s);
        // process the value (e.g. add it to a list for further processing)
    }
}

答案 2 :(得分:2)

如果你被允许使用Apache Commons Collections 4,你可以使用SetUtils.difference(),这可能与@Tinaki的答案有相似的表现。

答案 3 :(得分:1)

这是一种基于流的快速,非破坏性的解决方案:

Map<Integer, String> a = ...;
Map<Integer, String> b = ...;
Set<String> bVal = new HashSet<String>(b.values());
String[] res = a.values()
    .stream()
    .filter(s -> bVal.contains(s))
    .toArray(String[]::new);

res包含两个地图中的所有。完成此代码后,两个地图都保持原始状态。

代码需要额外的内存大小与第二个映射的大小成比例。如果您的某个地图明显小于另一个地图,则可以通过在上面的示例中将较小的地图用作地图b来节省空间。

Demo.

答案 4 :(得分:0)

A.containsValue(value) && !B.containsValue(value)

请参阅:https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#containsValue(java.lang.Object)

答案 5 :(得分:0)

我假设你想要的唯一值不依赖于关键位置 (2,“你好”和1,“你好”)

单行代码应该这样做。

a.values().removeAll(b.values());

警告:这会删除'a'hashmap

中的所有重复值