[英]Groovy Strings vs Java Strings
我有一个用其他字符串制作的groovy字符串,例如:
def final PREFIX = "myprefix"
def prefix2 = PREFIX + ".whatever1"
现在假设我有一个HashMap
,我想使用prefix2
作为键的一部分进行查找:
HashMap<String,String> map = new HashMap<String,String>()
map.put("myprefix.whatever1.value","aaa")
如果我做:
def key = "${prefix2}.value"
String result=(map.get(key))
然后result = null
,但是如果我这样做:
String key="${prefix2}.value"
String result=(map.get(key))
然后result = aaa
。
我能理解为什么会发生这种情况,很明显是类型推断问题。 但是我仍然发现它让我感到恶心。 某些事情并不“感觉正确”。 你懂我的意思吗?
这种事情正常吗?应该“预期”吗? 我是否Hashmap <String, String>
Groovy知道是否如果我使用引号创建了字符串,那么当它用于在Hashmap <String, String>
查找值而不定义为String
对象引用时,它应该可以工作吗? 这是错误还是功能?
为什么要发生这种情况,需要考虑多个方面。
当您创建变量HashMap<String,String> map
您希望像在Java中一样,只能将字符串作为键和值添加到它。 groovy中不是这种情况,因为不会考虑类型参数,这意味着以下内容将起作用:
HashMap<String,String> map = new HashMap<String,String>()
map.put(1, 2)
assert map.get(1) == 2
assert map.get(1) instance of Integer
同样如您所述,插值字符串(例如"${prefix2}.value"
是GString
的实例( GStringImpl
是GStringImpl
),因此以下是正确的
def key = "${prefix2}.value"
assert key instanceof GString
因此,由于删除了String约束,因此将使用GString
参数无错误地调用map.get(key)
,如果GStringImpl
将给出与String
相同的哈希码,则不会有问题,但是不会
assert key == "myprefix.whatever1.value"
assert key.hashCode() != "myprefix.whatever1.value".hashCode()
这就是为什么地图上的get返回null
解决此问题的方法是,如您所说的使用toString()
或将GString分配给String变量( toString()
被隐式调用)
我希望的另一种方法是,不要将常规的Java样式映射访问与常规的混合使用。 如果您使用GString在地图上使用属性符号或索引索引的键,它将可以完美地工作:
def final PREFIX = "myprefix"
def prefix2 = PREFIX + ".whatever1"
// def map = [:] // shorter will be a LinkedHashMap
HashMap<String,String> map = [:] as HashMap // if you really need HashMap
map."myprefix.whatever1.value" = "aaa"
def key = "${prefix2}.value"
assert map[key] == "aaa"
assert map."${prefix2}.value" == "aaa"
assert map."$key" == "aaa"
您可以调用GString的toString()方法(groovy中的插值字符串),该方法将返回java.lang.String,因此,例如,如果您想使用这样的字符串从HashMap中检索值,则可以使用它像这样:
def prefix = "some.string"
map.get("${prefix}.value".toString())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.