Using Strings as Keys in Hash Maps
Here is a short summary of the official documentation on strings in Groovy.Â
Groovy has two different classes representing a string:
java.lang.String
Âgroovy.lang.GString
 (also called interpolated string in other programming languages)
The difference is that if you instantiate the string with an interpolated expression, you automatically create a GString instance.
var s = "Groovy" // normal String assert s instanceof String var gs = "This is ${s}" // interpolated expression creates a GString assert gs instanceof GString
There are couple of things you need to be aware of when using GStrings:
- GString is automatically converted to String whenever it is passed as a parameter to a method explicitly accepting String.
- When a method accepts Object, no conversion takes place.
- GString and String do not have the same hashCode.
Given these three points, using GString as a key in a hash map is quite tricky. Look at the following example:
def map = [:] def id = 1 def key = "key:${id}" // this is a GString map[key] = "Groovy" // automatic conversion from GString to String happens here. The value is stored with a String key assert map.containsKey(key) // THIS WILL FAIL because the containsKey method accepts Object, therefore no conversion to String happens. The key has different hashCode.
To get around this, the safest way according to the Groovy documentation is to avoid using GString as keys in hash maps at all. If you still want to use it, the following approach will work:
String key = "key:${id}" // explicitly setting the data type to String will work map.containsKey(key.toString()) // explicitly converting the key to String will work as well
Found an issue in documentation? Write to us.
Â