87

我发现方法的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;
4

5 回答 5

103

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

于 2010-04-28T11:02:18.133 回答
67

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

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

这里, a < b,a - b是正数。

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

此外,即使它确实有效,它也不会提供任何显着的性能改进,并且实际上可能会降低可读性。

也可以看看

  • Java Puzzlers Puzzle 65:一个可疑的奇怪传奇

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

于 2010-04-28T11:09:28.400 回答
9

简单来说,int类型不足以存储两个任意int值之间的差异。例如,15亿和-15亿之间的差值为30亿,但int不能持有大于21亿的价值。

于 2010-04-28T12:03:59.077 回答
3

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

于 2010-04-28T11:02:49.913 回答
2

除了溢出的东西,你应该注意减法的版本不会给出相同的结果

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

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

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}
于 2010-04-28T13:23:07.957 回答