我有一个类似于以下代码的Java代码:
for(MyClass myclassObject: input.classes()) {
if(myclassObject.getName().equals("Tom")) {
outputMap.put("output", myclassObject.getAge())
}
}
如何使用Groovy collectmap有效地编写此代码?
我能做
input.classes().collectEntries["output":it.getAge()]
但是如何在其上包含if
条件?
答案 0 :(得分:1)
您可以使用findAll
仅根据条件保留项目
,然后应用collectEntries
来转换找到的项目
@groovy.transform.ToString
class MyClass{
int age
String name
}
def classes = [
new MyClass(age:11, name:'Tom'),
new MyClass(age:12, name:'Jerry'),
]
classes.findAll{it.getName()=='Tom'}.collectEntries{ [output:it.getAge()] }
答案 1 :(得分:0)
collectEntries
可以将闭包作为参数。您可以在闭包内部应用逻辑,并确保在条件通过时返回Map Entry,在条件失败时返回空Map。因此;
input.classes().collectEntries { MyClass myClassObject ->
myClassObject.name == 'Tom' ? ['output': myClassObject.getAge()] : [:]
}
但是,您的方法存在一个警告。由于您将密钥用作output
,并且Map不允许重复的密钥,因此,您将始终以map中的最后一个条目结束。如果这不是您的意图,则必须提出一个更好的计划。
答案 2 :(得分:0)
由于您生成的地图始终仅保留一个值,因此您也可以这样做:
input.classes().findResult { it.name == 'Tom' ? [output: it.age] : null }
其中findResult将返回classes()
中第一个关闭的项目:
{ it.name == 'Tom' ? [output: it.age] : null }
返回一个非空值。
由于您在问题中提到了效率:这比使用collectEntries
或findAll
遍历整个集合更有效,因为findResult
直接在找到{{1 }}。
哪种方法真正取决于您的要求。