首页 > 解决方案 > groovy中最小调用中的比较器与闭包?

问题描述

我试图了解将 aClosure与 a传递给集合上Comparator的函数之间的区别:min

// Example 1: Closure/field/attribute?
Sample min = container.min { it.timespan.start }

// Example 2: Comparator
Sample min2 = container.min(new Comparator<Sample>() {
  @Override
  int compare(Sample o1, Sample o2) {
    return o1.timespan.start <=> o2.timespan.start
  }
})

他们都返回正确的结果。

在哪里:

class Sample {
    TimeSpan timespan
    static constraints = {
    }
}

和:

class TimeSpan {
  LocalDate start
  LocalDate end
}

示例 1中,我只是传递了一个字段timespan.startmin我猜这意味着我正在传递一个Closure(即使它只是一个类中的一个字段)?

示例 1中,groovy 是否将字段timespan.start转换为像我在示例 2Comparator中明确创建的那样的幕后字段?

标签: groovy

解决方案


不同之处在于,这是两种不同的min方法,都采用不同的论点。有一个用于传递闭包 ,一个用于 比较器 (第三个使用标识和一些已弃用的标识,但我们现在可以忽略它)。

第一个版本(Closure带有一个(隐式参数))你必须从传递的值中提取值,你想用它来min 聚合。因此,这个版本有一些内部工作来处理比较值。

但文档还指出:

如果闭包有两个参数,它就像传统的比较器一样使用。即它应该比较它的两个参数的顺序,当第一个参数分别小于、等于或大于第二个参数时,返回一个负整数、零或一个正整数。否则,假设闭包采用单个参数并返回一个 Comparable(通常是一个整数),然后将其用于进一步比较。

因此,您也可以使用与第二个示例相同的闭包版本(您必须明确定义两个参数):

container.min{ a, b -> a <=> b }

第二个示例还有一个较短的版本。您可以使用 groovy 将闭包强制转换为接口。所以这也有效:

container.min({ a, b -> a <=> b } as Comparator)

推荐阅读