2010-11-11 128 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()); 

你如何處理一系列地圖的依賴正是你需要用他們做的,你沒有真正解釋過......但你可以通過他們循環做每一對地圖的上述操作,以確保最後的地圖至少有每個其他地方的每個條目地圖,例如。