Groovy 内置排序方法 vs 飞船操作符

Groovy built-in sorting method vs spaceship operator

Groovy 的列表有一个 sort() 方法,您可以向该方法提供对集合进行排序的标准。例如:

def foo = ["abc", "de", "fghi"]
println foo.sort { it.size() }

显示“[de, abc, fghi]”。 我认为引擎盖下的这种机制使用 spaceship 运算符调用 Java 的方法,因为以下代码片段显示相同的结果:

def foo = ["abc", "de", "fghi"]
def bar = ["abc", "de", "fghi"]
println foo.sort { it }
println bar.sort { a, b -> a <=> b }

然而,事实并非如此,因为:

def someDate = new Wrapper(new Date())
def someString = new Wrapper("16")
def someNumber = new Wrapper(4)
def foo = [someDate, someString, someNumber]
def bar = [someDate, someString, someNumber]
println foo.sort { it.value } // Produces "valid" output: [4, 16, Wed Jun 01..]
println foo.sort { a, b -> a.value <=> b.value} // Throws ClassCastException

//Simmulates JSON object I am working with
class Wrapper {
  Object value
  Object value2
  Wrapper(value) {
    this.value = value
  }

  @Override
  String toString() {
    return value
  }
}

那么,它究竟是如何运作的呢?有什么方法可以让我在排序参数中使用这样一个 Groovish 比较器并稍微调整一下(例如,这样我就可以按第二顺序按字段 value2 的值排序)?

当您将 sort{x->...} 与一个参数一起使用时,将使用 OrderBy comparator

对我来说,当你在同一个列表中有不同的类型时,结果是不可预测的。

只需尝试 运行 并预测以下脚本的输出:

println( ['xx', new Date(), 1199999999].sort{it} )
println( ['xx', new Date(), 11999999999].sort{it} )

但是如果你想使用它:

println foo.toSorted ( new OrderBy([{it.value},{it.value2}]) )