Home > Software design >  Groovy built-in sorting method vs spaceship operator
Groovy built-in sorting method vs spaceship operator

Time:06-02

Groovy's lists has a sort() method to which you can provide a criterion by which to sort the collection. For example:

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

displays "[de, abc, fghi]". I thought that this mechanism under the hood calls the Java's method with the spaceship operator, because the following code snippets displays the same result:

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

However, this is not the case, because:

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

So, how does it really work? Is there any way I can get such a Groovish comparator used in sort parameter and tune it a bit (for example, so that I can sort by the value of field value2 in the second order)?

CodePudding user response:

when you are using sort{x->...} with one param then OrderBy comparator is used.

as for me the result is unpredictable when you have different types in the same list.

just try to run to predict output for the following script:

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

however if you want to use it:

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