Groovy / Grails LinkedHashMap表现得很奇怪
我在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] 在集成测试中,我看到了相反的行为 – 我只能这样做 这种行为是预期的还是已知的? 解决方法
第一:不要在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语法.
这很可能是因为你的hashmap中的键是保留了一个GString. 如果GString没有任何变量,Groovy编译器会静默地将其转换为String文字(更好的性能),这就是为什么上面的例子实际上使用String作为键,但查找是使用GString. 例如 "Hello $name" -> GString('Hello $name') "Hello Bob" -> 'Hello Bob' 最后的想法:只要你处于groovy,就不要使用get(),因为Groovy提供了更清晰的[]和属性语法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |