Во-первых: не используйте GStrings в ключах hashmap. Когда-либо. У вас почти всегда будет проблема с возвратом элемента, потому что GString is not a String (красная рамка на этой странице) и не имеет того же значения хэш-функции. Вместо этого используйте один из следующих вариантов:
def key = 'key'
['key': value]
[(key): value]
[("some $key".toString()): value]
Это гарантирует, что вы всегда получите результат при использовании строки. (Итак, для поиска всегда используйте также String).
Я не уверен на 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 (String)).
Это, скорее всего, из-за того, что ваш ключ в вашем hashmap остается GString.
Если GString не имеет каких-либо переменных, компилятор Groovy бесшумно преобразует его в строковый литерал (более высокая производительность), поэтому приведенный выше пример фактически использует String в качестве ключа, но поиск использует GString ,
например.
"Hello $name" -> GString('Hello $name')
"Hello Bob" -> 'Hello Bob'
Последняя мысль: До тех пор, пока вы находитесь в заводной, не используйте get()
, так как Groovy обеспечивает гораздо более чистых []
и недвижимость синтаксисом.
+1 Для окончательной мысли :). Я также хотел бы отметить, что 'map ['key']' и 'map.key' являются просто синтаксическим сахаром для' map.getAt (key) '; и да, я бы рекомендовал всегда использовать эти два предыдущих варианта, если это возможно. – epidemian
Спасибо за такой исчерпывающий ответ. – Alex
Как и следовало ожидать, в моем приложении были клавиши карты GStrings. Добавили '.toString()' вызовы, и теперь карты ведут себя как ожидалось. Спасибо: ¬) – Alex