第一:不要在你的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