最近,我在我們的代碼基於一個錯誤,我發現查找一個HashMap中的值由字符串產生正確的結果,而查找由GStringImpl值使用「$ {key}」產生了一個不正確的(null)結果。下面是一個試驗我在Groovy的控制檯所做的:GroovyString hashCode和等於不計算爲相同的值作爲字符串
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
現在,如果我改變地圖的定義是TreeMap的這樣的實施方案如下所示:
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(),並且在使用equals(...)時不會生成真正的結果?這是一個錯誤/設計錯誤?還是這樣做是有原因的?看起來這些方法的結果應該是兼容的,因爲這些類之間的交互應該對程序員是無縫的。這樣做的結果是代碼中出現錯誤的巨大潛力,可能起初看起來很直觀,但會導致地圖查找中的錯誤。
謝謝,
克里斯
+1的鏈接。我希望能早些時候引用你引用的部分的引用:「兩種類型之間沒有自動強制進行比較或映射鍵的操作,所以有時需要在GString對象上顯式調用toString()。」對我來說,它似乎仍然是違反直覺的......但是我會接受你的回答,因爲這在Groovy文檔中有明顯的記錄,我假設他們不打算改變它。 –