第一:不要在你的HashMap的键使用GString的。永远。您几乎总会遇到检索该项的问题,因为GString is not a String(该页面上的红色框)并没有相同的散列值。相反,请使用以下选项之一:
def key = 'key'
['key': value]
[(key): value]
[("some $key".toString()): value]
这可确保您在使用字符串时始终能得到结果。 (因此,对于查找,总是用一个字符串,太。)
我不是100%肯定,为什么你看到的奇怪行为,但我有一个坚实的猜测。 get()
方法是Java方法,而数组样式(可能是属性样式)查找是使用getAt()
实现的,这是一种Groovy(GDK)方法。我的猜测是Groovy方法知道GStrings,并默默地处理转换,以确保不会被绊倒。
最简单的办法是始终使用getAt()
,不get
:
def m = ['smart-1':[stuff:'asdf']]
println m.getClass()
def p = [id:1]
println m."smart-$p.id"
println m["smart-$p.id"]
println m.getAt("smart-$p.id")
println m.'smart-1'
println m['smart-1']
println m.getAt('smart-1')
工作正常。
更好的解决办法是,以确保您正在查找值的时候,像这样使用字符串:
println m.get("smart-$p.id".toString())
也可以工作。我更喜欢这种方法,因为直接调用方法时,键更清晰。在使用数组样式或属性样式访问器时,我仍然使用普通的GString,因为这是标准的Groovy语法。
在一个集成测试,我看到相反的行为 - 我只能得到使用HashMap的m.get(GStringImpl)(相m.get(字符串))的内容。
这很可能是因为你的密钥在你的hashmap中保留了一个GString。
如果一个GString没有任何变量,Groovy编译器将其默认地转换为一个字符串文本(性能更好),这就是为什么上面的例子实际上使用String作为关键字,但是查找使用GString 。
例如
"Hello $name" -> GString('Hello $name')
"Hello Bob" -> 'Hello Bob'
最后一个想法:只要你是在Groovy中,不使用get()
,因为Groovy提供了更清洁[]
和财产语法。
+1对于最终的想法:)。我还想指出'map ['key']'和'map.key'只是'map.getAt(key)'的语法糖;是的,如果可能的话,我建议你总是使用这两个前选项。 – epidemian
感谢您的全面回答。 – Alex
可疑的是,我的应用程序中的地图键是GStrings。已经添加了'.toString()'调用,现在地图的行为如预期。感谢:¬) – Alex