groovy:在地图中安全地找到一个键并返回它的值

时间:2013-01-07 12:57:33

标签: dictionary groovy closures

我想在给定的地图中找到特定的密钥。如果找到了密钥,那么我想从地图中获取该密钥的值。

这是我到目前为止所做的:

def mymap = [name:"Gromit", likes:"cheese", id:1234]

def x = mymap.find{ it.key == "likes" }

if(x)
    println x.value

这样可行,输出是预期的“奶酪”。很好,但最后我不想做x.value,我不想做if(x)。我希望x以某种方式直接包含值。

我无法像以下那样将值直接输入x:

def mymap = [name:"Gromit", likes:"cheese", id:1234]

def x = mymap.find{ it.key == "likesZZZ" }.value

println x

因为在这种情况下find闭包为null,所以这会导致Null指针异常。当然,上面的代码段在it.key == "likes"时有效,但我不确定我是否总会在地图中找到目标键。

什么是“Groovier”并且在地图上安全地执行此操作:

  • 检查地图是否有给定的密钥
  • 如果是这样,请获取此密钥的值

5 个答案:

答案 0 :(得分:51)

使用地图的重点是直接访问。如果您确定地图中的值永远不会是Groovy - false,那么您可以这样做:

def mymap = [name:"Gromit", likes:"cheese", id:1234]
def key = "likes"

if(mymap[key]) {
    println mymap[key]
}

但是,如果值可能是Groovy - false,则应使用:

if(mymap.containsKey(key)) {
    println mymap[key]
}

最简单的解决方案,如果您知道该值不是Groovy - false(或者您可以忽略它),并且想要一个默认值,就像这样:

def value = mymap[key] ?: "default"

所有这三种解决方案都比示例快得多,因为它们不扫描整个地图中的密钥。他们利用HashMap(或LinkedHashMap)设计,使直接密钥访问几乎是即时的。

答案 1 :(得分:19)

def mymap = [name:"Gromit", id:1234]
def x = mymap.find{ it.key == "likes" }?.value
if(x)
    println "x value: ${x}"

println x.getClass().name

?.检查null并且不在Groovy中创建异常。如果密钥不存在,则结果为org.codehaus.groovy.runtime.NullObject

答案 2 :(得分:1)

通常,这取决于地图包含的内容。如果它具有空值,则事情可能会变得棘手,并且应使用containsKey(key)get(key, default)来检测元素是否存在。在许多情况下,代码可以变得更简单,您可以定义默认值:

def mymap = [name:"Gromit", likes:"cheese", id:1234]
def x1 = mymap.get('likes', '[nothing specified]')
println "x value: ${x}" }

另请注意,containsKey()get()比设置闭包以检查元素mymap.find{ it.key == "likes" }要快得多。如果你真的在那里做一些更复杂的事情,那么使用闭包才有意义。你可以,例如这样做:

mymap.find{ // "it" is the default parameter
  if (it.key != "likes") return false
  println "x value: ${it.value}" 
  return true // stop searching
}

或使用显式参数:

mymap.find{ key,value ->
  (key != "likes")  return false
  println "x value: ${value}" 
  return true // stop searching
}

答案 3 :(得分:0)

你得到空指针异常的原因是因为在你的第二个例子中没有关键词likeZZZ。尝试:

def mymap = [name:"Gromit", likes:"cheese", id:1234]
def x = mymap.find{ it.key == "likes" }.value
if(x)
    println "x value: ${x}"

答案 4 :(得分:0)

Groovy映射可以与property属性一起使用,因此您可以这样做:

def x = mymap.likes

如果您要查找的键('likes.key')本身包含一个点,则可以使用以下语法:

def x = mymap.'likes.key'