Dictionary 如果在没有Java8的Groovy中不存在,则放入映射
我需要把一个条目的地图,只有当钥匙还没有出现。对于Java8,我只想使用Dictionary 如果在没有Java8的Groovy中不存在,则放入映射,dictionary,groovy,Dictionary,Groovy,我需要把一个条目的地图,只有当钥匙还没有出现。对于Java8,我只想使用putIfAbsent,但我将Groovy用于Java7 说明问题的代码: 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
putIfAbsent
,但我将Groovy用于Java7
说明问题的代码:
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的某些功能来执行此操作,或者我需要手动执行此操作?您可以自己使用元编程:
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
我刚刚发现这同样有效:
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]
用原始条目覆盖默认条目就足够了。的解决方案非常优雅,但您也可以使用Java 1.5中引入的,并提供了方法。因此,您可以将代码实现为:
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;
还有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]
它不是重复的吗:?不,我不需要
Multimap
,只要HashMap
就可以解决我的问题是的,很好-但是ConcurrentHashMap
创建了很多ConcurrentHashMap$Segment
,ConcurrentHashMap$HashEntry[]
和ReentrantLock$NonfairSync
在内存中,对于如此简单的操作,看起来有点过分:)