Why are there different behaviors for the ways of addressing GString keys in maps?

别等时光非礼了梦想. 提交于 2019-11-27 15:53:17

You can look at this matter with a very different approach. A map is supposed to have immutable keys (at least for hashcode and equals), because the map implementation depends on this. GString is mutable, thus not really suited for map keys in general. There is also the problem of calling String#equals(GString). GString is a Groovy class, so we can influence the equals method to equal to a String just fine. But String is very different. That means calling equals on a String with a GString will always be false in the Java world, even if hashcode() would behave the same for String and GString. And now imagine a map with String keys and you ask the map for a value with a GString. It would always return null. On the other hand a map with GString keys queried with a String could return the "proper" value. This means there will always be a disconnection.

And because of this problem GString#hashCode() is not equal to String#hashCode() on purpose.

It is in no way non-deterministic, but a GString hashcode can change, if the participating objects change their toString representation:

def map = [:]
def gstring = "$map"
def hashCodeOld = gstring.hashCode()
assert hashCodeOld == gstring.hashCode()
map.foo = "bar"
assert hashCodeOld != gstring.hashCode()

Here the toString representation of map will change for Groovy and GString, thus the GString will produce a different hashcode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!