2012-12-25 60 views
3

我對Java還比較陌生,我發現自己一直在試圖正確編寫這段代碼,我覺得應該更簡單一些。比較兩張java地圖的關鍵和值

我有兩個地圖由同一個對象的兩個不同實例組成。鍵是對象,值是對象。

有兩個實例,因爲我試圖確定一個實例中的鍵是否與另一個實例中的鍵不同。我試圖專門定位新鍵或缺失鍵,然後比較兩個映射中存在的鍵的值。

下面的示例代碼只是爲了幫助可視什麼,我試圖做的(希望這不是更混亂!)

下面的示例的目標應該告訴我,「C」鍵丟失,有是一個新的鍵(「D」),然後它應該最終比較兩個映射中鍵的值。

主要問題是,有沒有辦法在一個循環中做到這一點?主要是因爲我的實際代碼會觸動文件系統在地圖的價值觀和我想它有觸摸盤

Map<objA, objB> mapA = new HashMap<objA, objB>(); 
mapA.put("A", "1"); 
mapA.put("B", "2"); 
mapA.put("C", "3"); 

Map<objA, objB> mapB = new HashMap<objA, objB>(); 
mapB.put("A", "1"); 
mapB.put("D", "4"); 

// Check if something is missing from mapB 
for(Map.Entry<objA, objB> entryMapA:mapA.entrySet()) 
{ 
    if(!mapB.containsKey(entryMapA.getKey()) 
     { 
      System.out.println(entryMapA.getKey() + " is missing"); 
     } 
} 

// Check if something is new is in mapB 
for(Map.Entry<objA, objB> entryMapB:mapB.entrySet()) 
{ 
    if(!mapA.containsKey(entryMapB.getKey()) 
    { 
     System.out.println(entryMapB.getKey() + " is new"); 
    } 
} 
+1

這聽起來酷似[番石榴的'Maps.difference'(http://docs.guava-libraries.googlecode.com/git-history/release/的Javadoc/COM /谷歌/普通/收集/ Maps.html#差(java.util.Map,%20java.util.Map))。 –

回答

8

鍵在MapSet S上的時間減少,所以你可以使用設置和可用的操作。

例如:

Set<String> keysInA = new HashSet<String>(mapA.keySet()); 
Set<String> keysInB = new HashSet<String>(mapB.keySet()); 

// Keys in A and not in B 
Set<String> inANotB = new HashSet<String>(keysInA); 
inANotB.removeAll(keysInB); 

// Keys common to both maps 
Set<String> commonKeys = new HashSet<String>(keysInA); 
commonKeys.retainAll(keysInB); 

等等等等

注意:切勿直接使用地圖的按鍵。如果你這樣做:

// This returns the actual key set of the map, NOT a copy! 
Set<String> inANotB = mapA.keysSet(); 
inANotB.removeAll(mapB.keySet()) 

你居然mapA刪除鍵(及其關聯值)。

最後,你應該注意,HashSet沒有訂單保證。如果這對你很重要,你想看看SortedSet(如TreeSet)的實現。

+0

原諒我的無知,但我不明白當你說「你不能直接使用地圖的關鍵集:它是可變的。」我仍然對編程不熟悉,所以有些術語很混亂......什麼是可變的? –

+1

@nkon:'.keySet()'返回的'Set'是地圖的實際鍵集。如果修改該集合,則可以修改地圖本身。並且你可能不希望這樣;) – fge

+1

@fge:如果你想在不改變原始地圖的情況下對集合進行破壞性修改,那麼你需要一個副本,但是沒有必要將每個**的兩個**副本作爲你的代碼是。 (我意識到你這樣做是爲了讓每個變量都是它自己的副本)。這是一個例子,其中函數式樣(返回新副本而不是變體方法的純函數)就像Louis在上面評論中提到的Guava實用程序一樣,更清晰的代碼。 –

1

您可以減去的按鍵組:

Set<objA> keysA1 = new HashSet<objA>(mapA.keySet()); // deepcopy 
Set<objA> keysA2 = new HashSet<objA>(mapA.keySet()); // deepcopy 
Set<objB> keysB = new HashSet<objB>(mapB.keySet()); // deepcopy 

keysA1.removeAll(keysB); 
keysB.removeAll(keysA2); 

System.out.println("Missing in A: " + keysB); 
System.out.println("Missing in B: " + keysA1); 
+2

差不多+1,但你的'// deepcopy'評論充其量是誤導性的。 'HashSet'構造函數只做**淺**副本。你在這裏擺脫了它,因爲字符串是不可變的,但是如果你在集合中有可變對象,那麼這些實例將在這些副本之間共享。 –