Groovy Map Quiz Redux

Monday, May 11, 2009

What will the following code fragment print?

def bar = 1
def foo = "a ${bar}"
def map = [:]
map[foo] = “val”
println map.containsKey(foo)

If, like me, you answered “true”, then you may want to read the rest of this post to be spared from spending more time than I care to admit figuring out why, in fact, it prints “false”.

It turns out that the culprit here involves using a GString as the key, which in and of itself it’s a problem, but it does cause some map methods (notably “containsKey” in this case) to behave not-as-expected. The reasoning behind this behavior (including why it won’t be fixed and proposed workarounds) is summed up in this bug report.

One of the proposed workarounds is to force early String conversion of the GString like so:

println map.containsKey(foo.toString())

But rather than having to remember to avoid “containsKey” in the presence of GStrings, I prefer to exploit the fact that Groovy “if” statements will return false if the test expression is null, as in:

if (map[foo])…

Of course this would only be equivalent to “containsKey” if you refrain from mapping to null values.

Top