2010-11-11 61 views
1

我有两个hashmaps。这只是2个hashmaps的例子,可以有n个hashmaps。散列图比较

他们看起来像这样

HashMap A = [(a, 23),(b,25),(c,43),(d,34)] 
HashMap B = [(a, 32),(b,52),(d,55)] 

现在我想将这些包含HashMap以这样的方式比较,这样我就可以把“C”的丢失钥匙插入HashMap的B带价值为0

我怎样才能做到这一点?请记住,可以有n个HashMaps。

回答

2

让我们调用“目标”HashMap,它将获得丢失的键和每个其他的“源”。

for (Map<String,Number> source : sources) { 
    for (String key : source.keySet()) { 
    if (!target.containsKey(key)) { 
     target.put(key, 0); 
    } 
    } 
} 

现在如果你想确保所有地图有所有按键与所有其他:对于每个源每个键,如果目标不包括键接零与目标该键关联地图,那么你应该首先计算整组按键和缺少的添加到每个地图:

Set<String> allKeys = new HashSet<String>(); 
for (Map<String,Number> map : allHashMaps) { 
    allKeys.addAll(map.keySet()); 
} 
for (Map<String,Number> map : allHashMaps) { 
    for (String key : allKeys) { 
    if (!map.containsKey(key)) { 
     map.put(key, 0); 
    } 
    } 
} 

这两种解决方案在澳进行(N * K),其中n是地图和k的数量是平均数每个地图中的按键。

+1

在第二种情况下,为了避免对'containsKey'进行N^2调用(这将有效地使你的函数O(N^2)),我宁愿计算键集差有问题的每张地图。函数仍然是O(N^2)(因为差分是O(N)并且执行了N次),但是常数因子可能会更低。 – 2010-11-11 21:47:35

+0

如果我将这些hashmaps从其他对象的循环中取出,我该如何做到这一点? – yogsma 2010-11-11 21:51:53

+0

真的,'Set#removeAll'将会在两个设置大小常量中的较小值处执行,但是具有相同的大哦。如果它在现实中有所不同,当然取决于数据的实际情况=) – maerics 2010-11-11 21:55:33

0
public static <T> void mergeKeys(Map<T, Integer> target, Map<T, ?>... sources) { 
    Set<T> newKeys = new HashSet<T>(); 
    for (Map<T, ?> source : sources) 
     newKeys.addAll(source.keySet()); 
    newKeys.removeAll(target.keySet()); 
    for (T key : newKeys) 
     target.put(key, 0); 
} 
1

你可以做A.keySet().removeAll(B.keySet()),这将给你都在一个不属于B中

+0

对keySet的修改也修改了底层映射;可能不希望(甚至不允许)修改“A”。 – Carl 2010-11-11 21:58:56

+0

真的,很好。 – 2010-11-11 22:03:47

0
Set<Key> keys = new HashSet<Key>(/* if you have any perspective on size, could put it here */); 
for (Map<Key, ?> map : n-maps) keys.addAll(map.keySet()); 
for (Map<Key, ?> map : n-maps) for (Key k : keys) if(!map.containsKey(k)) map.put(k, defaultObject); 

其中n-mapsIterable或您的地图阵列,以及defaultObject是你想放什么默认的项目在那里。

有一些明智的优化路线,像keys集的大小与目标map,这将允许您分支到一对夫妇的明智类的:相同的大小,非常接近0或keys.size(),或者其他。

3

Guava有东西可以帮助你在这里:

Map<K, V> a = ... 
Map<K, V> b = ... 
MapDifference<K, V> difference = Maps.difference(a, b); 

一个MapDifference然后允许你检查一下两个地图的差异,如哪些条目左侧Map各种事物有正确的没有按”吨,反之亦然。

如果你想确保有没有在地图a任何条目b没有,你可以做这样的事情:

b.putAll(difference.entriesOnlyOnLeft()); 

你如何处理一系列地图的依赖正是你需要用他们做的,你没有真正解释过......但你可以通过他们循环做每一对地图的上述操作,以确保最后的地图至少有每个其他地方的每个条目地图,例如。