如何用Groovy collectMaps表示地图

时间:2019-05-08 23:29:54

标签: groovy

我有一个类似于以下代码的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条件?

3 个答案:

答案 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 }

返回一个非空值。

由于您在问题中提到了效率:这比使用collectEntriesfindAll遍历整个集合更有效,因为findResult直接在找到{{1 }}。

哪种方法真正取决于您的要求。