2016-08-24 16 views
0

只有在密鑰不存在的情況下,我需要將條目添加到地圖。在Java 8我只用putIfAbsent,但我使用Groovy與Java 7如果在沒有Java的Groovy中缺席,請放到地圖中8

代碼能說明問題:

def map = [a: 1, b: 2, c: 3] 
def newEntries = [a: 11, b: 22, d: 44] 

def result = // put new entries to the map only if they are not present 

assert result == [a: 1, b: 2, c: 3, d: 44] 

是否有可能使用一些Groovy的功能來做到這一點還是我需要手動執行?

+0

這難道不是一種重複:http://stackoverflow.com/questions/15640525/how-do-i-add-multiple-groovy-map-entries-without-overwriting-the-current-entries? – Opal

+0

不,我不需要'Multimap',只是'HashMap'對我的問題很好 –

回答

1

你可以滾你自己與元編程:

Map.metaClass.putIfAbsent = { otherMap -> 
    otherMap.each { k, v -> 
     if (! delegate.keySet().contains(k)) { 
      delegate.put(k, v) 
     } 
    } 
    delegate 
} 

def map = [a: 1, b: 2, c: 3] 
def newEntries = [a: 11, b: 22, d: 44] 

def result = map.putIfAbsent(newEntries) 

assert [a: 1, b: 2, c: 3, d: 44] == result 
5

我只是想出了這個作品,以及:

def map = [a: 1, b: 2, c: 3] 
def newEntries = [a: 11, b: 22, d: 44] 

def result = newEntries + map 

assert result == [a: 1, b: 2, c: 3, d: 44] 

,這足以覆蓋使用原有的默認項。

1

@Michael Easter的解決方案非常優雅,但您也可以使用在Java 1.5中引入的java.util.concurrent.ConcurrentHashMap,並提供putIfAbsent(K key, V value)方法。因此,您可以實現代碼:

import java.util.concurrent.ConcurrentHashMap; 
def map = new ConcurrentHashMap([a: 1, b: 2, c: 3]) 

[a: 11, b: 22, d: 44].each() { k,v -> 
    map.putIfAbsent(k,v); 
} 

assert [a: 1, b: 2, c: 3, d: 44] == map; 
+0

是的,很好 - 但是'ConcurrentHashMap'創建了很多'ConcurrentHashMap $ Segment','ConcurrentHashMap $ HashEntry []'和'ReentrantLock $ NonfairSync'在內存中,對於這樣簡單的操作,它看起來像矯枉過正:) –

1

還有Groovy的Map.withDefault()方法,這是一個很好的協議更靈活,但是可以用於這一目的。該行爲就有所不同了,因爲默認值是不實際添加到地圖上,直到他們,首先請求:

def map = [a: 1, b: 2, c: 3] 
def newEntries = [a: 11, b: 22, d: 44] 

def result = map.withDefault { k -> newEntries[k] } 

assert result == map 
assert result != [a: 1, b: 2, c: 3, d: 44] 
assert newEntries.keySet().every { k -> result[k] == map[k] ?: newEntries[k] } 
assert result == [a: 1, b: 2, c: 3, d: 44] 
相關問題