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

问题描述 投票:0回答:5

我发现

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;
java optimization integer comparison integer-overflow
5个回答
106
投票

整数溢出

这是由于整数溢出造成的。当

thisVal
非常大且
anotherVal
为负数时,从前者中减去后者会得到大于
thisVal
的结果,这可能会溢出到负值范围。


70
投票

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

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

这里,

a < b
,但
a - b
是正数。

不要使用这个习语。没用。

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

另请参阅

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

    这个谜题有几个教训。最具体的是:不要使用基于减法的比较器,除非您确定值之间的差异永远不会大于

    Integer.MAX_VALUE
    。更一般地说,要小心
    int
    溢出。另一个教训是您应该避免“聪明”的代码。努力编写清晰、正确的代码,除非证明有必要,否则不要对其进行优化。


9
投票

简单来说,

int
类型不足以存储两个任意
int
值之间的差异。例如,15亿和-15亿之间的差异是30亿,但
int
不能容纳大于21亿的值。


3
投票

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


2
投票

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

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

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

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}
© www.soinside.com 2019 - 2024. All rights reserved.