Search code examples
javaintegercompareto

Integer compareTo() method, does it always return -1, 0 or 1?


The javadocs for the method compareTo() of the Integer class are extremely vague:

Returns: the value 0 if this Integer is equal to the argument Integer; a value less than 0 if this Integer is numerically less than the argument Integer; and a value greater than 0 if this Integer is numerically greater than the argument Integer (signed comparison)

The phrasing "a value less than 0" makes it seem like I can expect compareTo() to return all sort of negative integers (-1, -20, -9999, etc). Same for "a value greater than 0", it could really be anything above 0.

I noticed the method tends to return -1 and 1, however from the javadocs there is no guarantee that this behavior will be consistent. All I'm allowed to expected is an integer less than 0 or greater than 0, which could really be anything.

Does the function indeed always return -1, 0, or 1? Or does it occasionally return other values?

If it only returns -1, 0, and 1, why is that not clearly stated in the javadocs?

Example:

Integer myInteger = 8;
System.out.print(myInteger.compareTo(5));
// This prints 1

EDIT:

Interestingly, IntelliJ acts as if compareTo() always returns -1, 0, or 1. That is, if you have the following code:

public int myCompare(int x, int y){
    if(x == y){
        return 0;
    } else if(x < y){
        return -1;
    } else{
        return 1;
    }
}

IntelliJ will give the warning "Expression can be replaced with 'Integer.compare'", and recommend the method be changed to:

public int myCompare(int x, int y){
    return Integer.compare(x, y);
}

Solution

  • It is (IMO) unlikely that they will change the implementation of Integer. However the spec for Integer.compareTo does not state that the result is -1, 0 or +1 ... so they >could< change it. And if they do, then your code that relied on it would break.

    So if I want to guarantee it returns -1, 0 or 1, I have to wrap it with a Integer.signum()?

    Correct. Or implement your own Comparator or compareTo method ... if that is viable.

    If you are concerned about performance, there is a good chance that the JIT compiler will inline signum(compareTo(anInteger)). It may even optimize away the redundant signum logic ...

    If it only returns -1, 0, and 1, why is that not clearly stated in the javadocs?

    We can't speak for the people who wrote the spec. However, I imagine that they didn't want to preclude the possibility of changing the implementation; e.g. for (hypothetical) performance reasons.