加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy / Grails LinkedHashMap表现得很奇怪

发布时间:2020-12-14 16:27:17 所属栏目:大数据 来源:网络整理
导读:我在LinkedHashMap中遇到了一些令人困惑的行为 grails 2.0.3.在grails控制台中运行以下脚本: 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.get("smart-$p.id")println
我在LinkedHashMap中遇到了一些令人困惑的行为
grails 2.0.3.在grails控制台中运行以下脚本:

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.get("smart-$p.id")

println m.'smart-1'
println m['smart-1']
println m.get('smart-1')

给出输出:

class java.util.LinkedHashMap
[stuff:asdf]
[stuff:asdf]
null
[stuff:asdf]
[stuff:asdf]
[stuff:asdf]

在集成测试中,我看到了相反的行为 – 我只能这样做
使用m.get(GStringImpl)获取HashMap的内容(相反
m.get(字符串)).

这种行为是预期的还是已知的?

解决方法

第一:不要在hashmap键中使用GStrings.永远.检索项目几乎总是有问题,因为 GString is not a String(该页面上的红色框),并且没有相同的哈希值.相反,请使用以下选项之一:

def key = 'key'
['key': value]
[(key): value]
[("some $key".toString()): value]

这可确保您在使用String时始终获得结果. (因此,对于查找,也总是使用String.)

我不是百分百肯定你为什么会看到奇怪的行为,但我有一个可靠的猜测. get()方法是一个Java方法,而数组样式(可能是属性样式)查找是使用getAt()实现的,这是一个Groovy(GDK)方法.我的猜测是Groovy方法知道GStrings,并默默处理转换,以确保你不会被绊倒.

最简单的解决方案是始终使用getAt(),而不是获取:

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语法.

In an integration test,I’m seeing the opposite behaviour – I can only get the content of the HashMap using m.get(GStringImpl) (as opposed m.get(String)).

这很可能是因为你的hashmap中的键是保留了一个GString.

如果GString没有任何变量,Groovy编译器会静默地将其转换为String文字(更好的性能),这就是为什么上面的例子实际上使用String作为键,但查找是使用GString.

例如

"Hello $name" -> GString('Hello $name')
"Hello Bob"   -> 'Hello Bob'

最后的想法:只要你处于groovy,就不要使用get(),因为Groovy提供了更清晰的[]和属性语法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读