Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Comparable return value, does it have to be exactly 1, -1 or 0?

This might be a trivial question, but I have not found anything about it, so here goes:
When implementing the Comparable interface, we are supposed to define the method compareTo(), so that the following is true according to the documentation:

  • sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.

  • The relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.

  • x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.

Now, the part that gets confusing is the return value, that is specified as follows:

Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

It seems that most implementations return 1, -1 or 0, even though it is not mentioned as a requirement that the return value is limited in this way.
The following code thus works for Sorting a list (using Collections.sort()) containing instances of a class, Foo:

public int compareTo(Foo other){
    return this.value > other.value? 1 : this.value < other.value ? -1 : 0;
}

This however do not:

public int compareTo(Foo other){
    return (int)(this.value - other.value);
}

Where value is a long, and the difference between the values do not exceed Integer.MAX_VALUE.

Am I missing something here, or is the return value required to be exactly 1, -1 or 0, contradictory to the documentation?

Update: Thanks for all your answers, but it seems that the human factor was to blame here. I mentioned that the calculated difference was less than Integer.MAX_VALUE, which should mean that there is no overflow, but my calculations were wrong, so I did actually get overflow, which caused the strange results.

like image 237
Jave Avatar asked Feb 22 '23 15:02

Jave


1 Answers

The contract was so flexible to allow this.value - other.value idioms (which later turned out to be incorrect due to integer overflow). But in some cases it is still valueable, like str.length() - str2.length(). It is unlikely impossible that string or array size comparison will overflow since the minimum length is 0 and the maximum is Integer.MAX_VALUE (0 - Integer.MAX_VALUE is still greater than Integer.MIN_VALUE) so it is convenient when you need to sort by length/size.

Also comparing to 0 (greater-than/less-than) is often faster/genrates smaller bytecode/assembly than comparing to 1/-1, so why limit the users? You are absolutely free to use any positive/negative value.

like image 194
Tomasz Nurkiewicz Avatar answered Mar 15 '23 22:03

Tomasz Nurkiewicz