Java Integer compareTo() - 为什么使用比较与减法?

时间:2010-04-28 10:59:45

标签: java optimization comparison integer overflow

我发现java.lang.Integer方法的compareTo实现如下:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

问题是为什么使用比较而不是减法:

return thisVal - anotherVal;

5 个答案:

答案 0 :(得分:90)

这是由于整数溢出造成的。如果thisVal非常大且anotherVal为负数,则从前者中减去后者会产生大于thisVal的结果,该结果可能溢出到负范围。

答案 1 :(得分:62)

比较两个数值的减法“技巧”被打破!!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

此处a < b,但a - b为正。

请勿使用此成语。它不起作用。

此外,即使它可以正常工作 NOT 也会提供性能上的任何重大改进,实际上可能会带来成本可读性。

另见

  • Java Puzzlers谜题65:可疑排序的奇怪传奇
      

    这个谜题有几个教训。最具体的是:除非您确定值之间的差异永远不会大于 Integer.MAX_VALUE,否则不要使用基于减法的比较器。更一般地说,要小心int溢出。另一个教训是你应该避免“聪明”的代码。努力编写清晰,正确的代码,除非证明有必要,否则不要对其进行优化。

答案 2 :(得分:9)

简单来说,int类型不足以存储两个任意int值之间的差异。例如,15亿和-1.5亿之间的差异是30亿,但int不能超过21亿。

答案 3 :(得分:3)

也许是为了避免溢出/下溢。

答案 4 :(得分:1)

除了溢出之外,你应该注意带有减法的版本不会给出相同的结果

  • 第一个compareTo版本返回三个可能值之一:-1,0或1。
  • 如果用减法替换最后一行,结果可以是任何整数值。

如果你知道没有溢出,你可以使用这样的东西:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}