Ok, thanks for the clarification. We had been very very much irritated by this code causing a vulnerability issue. It is not out of question, since the example exploit for CVE-2015-3253 you mentioned actually does misuse a sorting structure in Java for the exploit. so I could not totally exclude such a possibility.
Anyway... back to the problem.
def a = [new Foo("foo")]
def b = [new Foo("foo")]
The basic problem is as follows.. if the objects are somehow comparable, then you can do disjoint in O(nlogn), by first sorting one and then checking against the other. If the objects are not comparable and if I can only check for equality, then I am required to use an O(n*n) approach, by checking each elements of one list, against each of the other.. well it is more like n*n/2, but that does not matter when looking at the complexity. So in older versions we first did check both lists if all elements are Comparable, to then later decide on the strategy and go with the nlogn of the n*n variant. But this approach did also not get the desired results, as can be seen in the test in 286532c
But I am wondering now... maybe the better approach is to add one more check like
if (o1.getClass()==o2.getClass() && (o1.equals(o2)) return 0;
But I wonder what we are supposed to return if equals gives false. If we say we return only 0, we could also think about removing the class check. or we keep the class check and return -1 in case of equals returning false.