Details
-
New Feature
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
-
None
Description
When working with Maps, there are two scenarios:
- You want a special default value if a key doesn't exist (ie. not "null")
- You want to create a new object if a key doesn't exist
Proposed syntax:
def map = new HashMap (defaultValue:'xxx')
map.put ('x', 'a')
assert map.x == 'a'
assert map.y == 'xxx'
map = [:]
x = map.get ('y') {
'New ${it}'
}
assert x == 'New y'
assert map.size() == 1
assert map.keys() = [ 'y' ]
map = [:] {
'New ${it}'
}
x = map.y
assert x == 'New y'
assert map.size() == 1
assert map.keys() = [ 'y' ]
Abstract: You can specify a constant value or a closure when creating a map and when getting values from it.
If a key doesn't exist, the constant will be returned or the result of running the closure. The missing key is the parameter for the closure.
Note: For checking if a key doesn't exist, it's not sufficient to check whether map.get() returns null because Maps can contain null values.
Implementation note: I suggest to implement this using a wrapper DefaultValueMap which handles the default case. All methods but get() are simply forwarded to the wrapped Map. get() looks like this:
public Object get(Object key)
{ if (!containsKey(key)) return defaultValue; return super.get(key); }Open questions:
- What happens when the closure returns null? Maybe the new key/value pair shouldn't be added in this case. Or do we want to add a new exception for this?