Groovy字符串与Java字符串 [英] Groovy Strings vs Java Strings

查看:285
本文介绍了Groovy字符串与Java字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在其他字符串中创建了一个groovy字符串,例如:

  def final PREFIX =myprefix
def prefix2 = PREFIX +.whatever1

现在假设我有一个 HashMap ,我想使用 prefix2 作为键的一部分:

 的HashMap<字符串,字符串> 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



我可以理解为什么会发生这种情况,显然是类型推断问题。但我仍然觉得它让我感到恶心。有些事情对此并不感觉正确。你知道我的意思吗?



这种事情是正常的,应该是预期的?我是否要求Groovy知道如果我使用引号创建了字符串,它应该用于在 Hashmap< String,String> 没有被定义为字符串对象引用?这是一个错误还是一个特性?

解决方案

有很多事情需要考虑为什么会发生这种情况。 / p>

创建变量 HashMap< String,String> map 你会期望像在java中一样,你只能添加字符串作为键和值。常规情况并非如此,因为类型参数将不被考虑,这意味着以下内容将起作用:

pre $ HashMap<字符串,字符串> map = new HashMap< String,String>()
map.put(1,2)
断言map.get(1)== 2
断言map.get(1)同样如您所述,插值字符串如$ {prefix2} .value是一个 GString GStringImpl 具体)的实例,所以以下是真的


  def key =$ {prefix2} .value
断言密钥instanceof GString

因此, map.get(key)会被调用 GString 参数没有错误,因为String约束被删除,如果 GStringImpl 会给出与字符串相同的哈希码,但它不是

  assert key ==myprefix.whatever1.value
assert key.hashCode()!=myprefix.whatever1.value.hashCode()

这就是为什么get map会返回一个 null



<解决这个问题的方法是,正如你所说的使用 toString()或将GString赋值给一个String变量( toString()隐式调用)另一种方式,我更喜欢的是不要将常用的java风格地图访问与常规风格的地图访问混合在一起。如果您使用GString的地图符号或索引键,它可以很好地工作:

  def final PREFIX =myprefix 
def prefix2 = PREFIX +.whatever1

// def map = [:] // short将是一个LinkedHashMap
HashMap< String,String> map = [:] as HashMap //如果你确实需要HashMap
map。myprefix.whatever1.value=aaa

def key =$ {prefix2} .value

assert map [key] ==aaa
断言映射$ {prefix2} .value==aaa
断言映射$ key= =aaa


I have a string in groovy that I make from other strings, example:

def final PREFIX = "myprefix"
def prefix2 = PREFIX + ".whatever1"

Now suppose I have a HashMap and I want to do a lookup using prefix2 as part of a key:

HashMap<String,String> map = new HashMap<String,String>()
map.put("myprefix.whatever1.value","aaa")

If I do:

def key = "${prefix2}.value"
String result=(map.get(key))

Then result = null, but if I do:

String key="${prefix2}.value"
String result=(map.get(key))

Then result = aaa.

I can understand why this happens, obviously a type inference issue. But I still find it makes me feel icky. Something just doesn't "feel right" about it. Do you know what I mean?

Is this type of thing normal and should be "expected"? Am I asking for too much for Groovy to know that if I created the string using quotes, it should work when being used to look up a value in a Hashmap <String, String> without being defined as a String object reference? Is this a bug or a feature?

解决方案

There are multiple things that need to be take into consideration why this is happening.

When you create a variable HashMap<String,String> map you would expect that like in java you would only be able to add strings as keys and values to it. This is not the case in groovy as the type arguments will not be taken into consideration which means the following will work:

HashMap<String,String> map = new HashMap<String,String>()
map.put(1, 2)   
assert map.get(1) == 2
assert map.get(1) instance of Integer

Also as you stated, an interpolated string like "${prefix2}.value" is an instance of GString (GStringImpl to be specific) so the following is true

def key = "${prefix2}.value"
assert key instanceof GString

So, map.get(key) will get invoked with a GString parameter without an error since the String constraint is dropped, which would not be an issue if the GStringImpl would give the same hashcode as the String, but it doesn't

assert key == "myprefix.whatever1.value"
assert key.hashCode() != "myprefix.whatever1.value".hashCode()

This is why the get on the map returns a null

The way to work around this is, as you stated using either toString() or assigning the GString to a String variable (toString() is called implicitly)

Another way, which I would prefer, is to not mix the usual java style map access with the groovy one. If you use the property notation or key indexed on the map using the GString it will work perfectly:

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"

这篇关于Groovy字符串与Java字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆