我想在给定的地图中找到特定的密钥。如果找到了密钥,那么我想从地图中获取该密钥的值。
这是我到目前为止所做的:
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”并且在地图上安全地执行此操作:
答案 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'