Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GroovyString hashCode和equals的计算结果与String的值不同_String_Map_Groovy - Fatal编程技术网

GroovyString hashCode和equals的计算结果与String的值不同

GroovyString hashCode和equals的计算结果与String的值不同,string,map,groovy,String,Map,Groovy,最近,我在我们的代码库中处理一个bug,我发现通过字符串查找HashMap中的值会产生正确的结果,而通过GStringImpl使用“${key}”查找值会产生错误的(null)结果。以下是我在Groovy控制台中进行的测试: def myMap = ["testString" : "value"] def testString = "testString" println myMap.get("${testString}") println myMap[testString] println "

最近,我在我们的代码库中处理一个bug,我发现通过字符串查找HashMap中的值会产生正确的结果,而通过GStringImpl使用“${key}”查找值会产生错误的(null)结果。以下是我在Groovy控制台中进行的测试:

def myMap = ["testString" : "value"]
def testString = "testString"
println myMap.get("${testString}")
println myMap[testString]
println "${testString}".getClass()
println testString.getClass()

String myString = "test"
def myGroovyString = "${myString}"

println myString.equals(myGroovyString)
println myString.hashCode()
println myGroovyString.hashCode()
println myString.compareTo(myGroovyString)
产出如下:

null
value
class org.codehaus.groovy.runtime.GStringImpl
class java.lang.String
false
3556498
3556535
0
def myMap = ["testString" : "value"] as TreeMap
现在,如果我将map的定义更改为TreeMap的实现,例如:

null
value
class org.codehaus.groovy.runtime.GStringImpl
class java.lang.String
false
3556498
3556535
0
def myMap = ["testString" : "value"] as TreeMap
我得到以下结果:

value
value
class org.codehaus.groovy.runtime.GStringImpl
class java.lang.String
false
3556498
3556535
0
我知道发生这种情况的原因可能是(我没有研究HashMap与TreeMap的实现)HashMap通过hashCode()查找键,而TreeMap将使用compareTo(…)。我的问题是,为什么String和GStringImpl在使用等于(…)时不生成相同的hashCode(),也不生成真正的结果?这是错误/设计错误吗?还是这样做是有原因的?似乎这些方法的结果应该是兼容的,因为这些类之间的交互对于程序员来说应该是无缝的。这样做的结果是,代码中可能会出现错误,这些错误起初看起来很直观,但会导致地图查找中出现错误

谢谢


Chris(Groovy中默认的
Map
类型)基于对象的
hashCode
执行查找

TreeMap
对树的根执行
compareTo
调用,并根据调用结果从左分支或右分支下移(如果
key.compareTo(node.key)
返回
0
,则返回值)

如你所见

println myString.compareTo(myGroovyString)
打印
0
。这就是为什么在
TreeMap
中找到该项,而不同的
hashCode
就是为什么在
LinkedHashMap中找不到该项的原因


Groovy字符串不是字符串,而是一种模板机制和一个完全不同的对象。这就是为什么对于
hashCode
,您会得到不同的结果——有关链接,请参见+1。我希望我能更早地从您引用的部分中捕捉到这句话:“这两种类型之间没有自动强制进行比较或映射键,因此有时有必要在GString对象上显式调用toString()这对我来说似乎仍然是违反直觉的…但我会接受你的答案,因为这显然在Groovy文档中有很好的文档记录,我假设他们不打算更改它。