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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With