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

Vla*_*mir 78 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));
}
Run Code Online (Sandbox Code Playgroud)

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

return thisVal - anotherVal;
Run Code Online (Sandbox Code Playgroud)

Ita*_*man 92

这是由于整数溢出.当thisVal非常大且anotherVal为负时,从后者中减去后者产生的结果大于thisVal可能溢出到负范围的结果.


pol*_*nts 63

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

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"
Run Code Online (Sandbox Code Playgroud)

这里a < b,又a - b是积极的.

不要使用这个成语.它不起作用.

而且,即使它确实有效,它也不会在性能上提供任何显着的改进,并且实际上可能具有成本可读性.

也可以看看

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

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

  • @naiad只做`((long)a - b)`没有帮助,因为你必须将结果强制转换回`int`,因为这是比较器必须返回的结果,再次以溢出结束.您必须在结果上执行类似"Long.signum"的操作,这很容易忘记,正如您的评论所示.它甚至可能不比`Integer.compare`更有效率,JVM可能会内在地处理它...... (3认同)
  • 它根本没有真正破碎.如果您对所比较的数字一无所知,您可能会知道它们可以安全地进行比较.即使不知道,只要`((长)a - b)`应该工作.虽然你是对的; 它很少有用. (2认同)

fre*_*low 9

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