Groovy Map.get(key, default) 改变地图
Groovy Map.get(key, default) mutates the map
我有以下 Groovy 脚本:
mymap = ['key': 'value']
println mymap
v = mymap.get('notexistkey', 'default')
println v
println mymap
当我 运行 它时,我得到以下控制台输出:
[key:value]
default
[key:value, notexistkey:default]
令我惊讶的是,在调用 mymap.get('notexistkey', 'default')
之后,第二个参数是给定键不存在时返回的默认值,键 notexistkey
被添加到映射中,我调用了该方法在。为什么?这是预期的行为吗?我怎样才能防止这种突变?
改用Java的Map.getOrDefault(key, value)
:
mymap = ['key': 'value']
println mymap
v = mymap.getOrDefault('notexistingkey', 'default')
println v
println mymap
输出:
[key:value]
default
[key:value]
Groovy SDK 通过 DefaultGroovyMethods.get(map, key, default)
添加 Map.get(key, default)
,如果您看一下 Javadoc 所说的内容,您就会明白这种行为是预期的:
Looks up an item in a Map for the given key and returns the value - unless there is no entry for the given key in which case add the default value to the map and return that.
这就是这个方法的实现:
/**
* Looks up an item in a Map for the given key and returns the value - unless
* there is no entry for the given key in which case add the default value
* to the map and return that.
* <pre class="groovyTestCase">def map=[:]
* map.get("a", []) << 5
* assert map == [a:[5]]</pre>
*
* @param map a Map
* @param key the key to lookup the value of
* @param defaultValue the value to return and add to the map for this key if
* there is no entry for the given key
* @return the value of the given key or the default value, added to the map if the
* key did not exist
* @since 1.0
*/
public static <K, V> V get(Map<K, V> map, K key, V defaultValue) {
if (!map.containsKey(key)) {
map.put(key, defaultValue);
}
return map.get(key);
}
这是一个非常古老的概念(自 Groovy 1.0 以来)。但是我建议不要使用它 - 这个 .get(key, default)
操作既不是原子的,也不是同步的。当你在为并发访问而设计的 ConcurrentMap
上使用它时,问题就开始了——这个方法违反了它的契约,因为 containsKey
、put
和最终的 get
之间没有同步称呼。
我有以下 Groovy 脚本:
mymap = ['key': 'value']
println mymap
v = mymap.get('notexistkey', 'default')
println v
println mymap
当我 运行 它时,我得到以下控制台输出:
[key:value]
default
[key:value, notexistkey:default]
令我惊讶的是,在调用 mymap.get('notexistkey', 'default')
之后,第二个参数是给定键不存在时返回的默认值,键 notexistkey
被添加到映射中,我调用了该方法在。为什么?这是预期的行为吗?我怎样才能防止这种突变?
改用Java的Map.getOrDefault(key, value)
:
mymap = ['key': 'value']
println mymap
v = mymap.getOrDefault('notexistingkey', 'default')
println v
println mymap
输出:
[key:value]
default
[key:value]
Groovy SDK 通过 DefaultGroovyMethods.get(map, key, default)
添加 Map.get(key, default)
,如果您看一下 Javadoc 所说的内容,您就会明白这种行为是预期的:
Looks up an item in a Map for the given key and returns the value - unless there is no entry for the given key in which case add the default value to the map and return that.
这就是这个方法的实现:
/**
* Looks up an item in a Map for the given key and returns the value - unless
* there is no entry for the given key in which case add the default value
* to the map and return that.
* <pre class="groovyTestCase">def map=[:]
* map.get("a", []) << 5
* assert map == [a:[5]]</pre>
*
* @param map a Map
* @param key the key to lookup the value of
* @param defaultValue the value to return and add to the map for this key if
* there is no entry for the given key
* @return the value of the given key or the default value, added to the map if the
* key did not exist
* @since 1.0
*/
public static <K, V> V get(Map<K, V> map, K key, V defaultValue) {
if (!map.containsKey(key)) {
map.put(key, defaultValue);
}
return map.get(key);
}
这是一个非常古老的概念(自 Groovy 1.0 以来)。但是我建议不要使用它 - 这个 .get(key, default)
操作既不是原子的,也不是同步的。当你在为并发访问而设计的 ConcurrentMap
上使用它时,问题就开始了——这个方法违反了它的契约,因为 containsKey
、put
和最终的 get
之间没有同步称呼。