1

how sort works on list of lists when spaceship operator (compareTo) fails for list?

Note that it's not just equals, but compareTo (greater ,lower, or equal)

def v1=[1, 2, 0]
def v2=[1, 3, 0]

def v=[v2,v1]

println v
//prints> [[1, 3, 0], [1, 2, 0]]

v=v.sort()
assert v[0]==v1
println v
//prints> [[1, 2, 0], [1, 3, 0]]

c=c.sort{x,y-> y<=>x}
//throws Cannot compare java.util.ArrayList with value '[1, 3]' and java.util.ArrayList with value '[1, 2, 3]'

According to code above List<List>.sort() works.

According to Iterable.sort() documentation:

Sorts the Collection. Assumes that the collection items are comparable and uses their natural ordering to determine the resulting order.

The question why and how List<List>.sort() works in groovy?

Can somebody point me how comparison of arrays implemented in groovy for sort() operation?

daggett
  • 26,404
  • 3
  • 40
  • 56
  • Is it `v.sort{x,y-> y<=>x}`? – Rao Jun 27 '17 at 10:49
  • How about this - https://stackoverflow.com/questions/2544258/how-can-i-compare-two-lists-in-groovy – Rao Jun 27 '17 at 11:02
  • Well, don't use the `<=>` operator? The operator cannot guess how you'd like to compare the lists. How do you define which list is bigger? You have to define what criterion or criteria should be used to define the order and then you have to formulate it as code. If you are unsure how to do that, add your sorting requirements, when is one list smaller, when is one list bigger and when are two lists identical regarding the sorting. – Vampire Jun 27 '17 at 11:23
  • Thanks for comments/ The question is not how to implement the sort, but why and how `sort()` works for list of lists when according to documentation it should not. i modified the question to be more clear. – daggett Jun 27 '17 at 12:53

1 Answers1

1

The reason for the different behaviour, is because different methods are involved. When you call c.sort{x,y-> y<=>x}, this invokes Iterable.sort, which throws an exception because the elements of the list are not Comparable.

However, when you call v.sort(), you're invoking this method defined in DefaultGroovyMethods.java

public static <T> List<T> sort(Iterable<T> self) {
    return sort(self, true);
}

which invokes this:

public static <T> List<T> sort(Iterable<T> self, boolean mutate) {
    List<T> answer = mutate ? asList(self) : toList(self);
    Collections.sort(answer, new NumberAwareComparator<T>());
    return answer;
}

as you can see this provides a Comparator to determine the ordering of the list elements, so they don't need to be Comparable themselves.

Dónal
  • 185,044
  • 174
  • 569
  • 824
  • The [`NumberAwareComparator`](https://github.com/apache/groovy/blob/master/src/main/java/org/codehaus/groovy/runtime/NumberAwareComparator.java#L50) compares objects by `hashCode()` for non supported object types... 8-| – daggett Aug 30 '18 at 07:18