Java整数compareTo() – 为什么使用比较与减法?
我发现compareTo
方法的java.lang.Integer
实现如下所示:
public int compareTo(Integer anotherInteger) { int thisVal = this.value; int anotherVal = anotherInteger.value; return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); }
问题是为什么使用比较而不是减法:
return thisVal - anotherVal;
这是由于整数溢出。 当thisVal
非常大而thisVal
为负时,从前者减去后者产生的结果大于可能溢出到负范围的thisVal
。
减法“诀窍”来比较两个数值是否被打破了!!!
int a = -2000000000; int b = 2000000000; System.out.println(a - b); // prints "294967296"
在这里, a < b
,但a - b
是正数。
不要使用这个成语。 它不起作用。
而且, 即使它起作用 ,它也不会在性能上有任何显着的改进,并且事实上可能会降低可读性。
也可以看看
- Java益智游戏拼图65:奇怪的sorting奇怪的传奇
这个难题有几个教训。 最具体的是: 不要使用基于减法的比较器,除非您确定值之间的差异永远不会大于
Integer.MAX_VALUE
。 更一般地说,要小心int
溢出。 另一个教训是,你应该避免“聪明”的代码。 努力写清楚,正确的代码,不要优化它,除非certificate是必要的。
简单地说, int
types不足以存储两个任意int
值之间的差异。 例如,十五亿到十五亿的差额是30亿,但是不能超过21亿。
也许是为了避免溢出/下溢。
除了溢出的事情,你应该注意到与减法的版本不会给出相同的结果 。
- 第一个compareTo版本返回三个可能的值之一:-1,0或1。
- 如果用减法replace最后一行,结果可以是任何整数值。
如果你知道没有溢出,你可以使用这样的东西:
public int compareTo(Integer anotherInteger) { return sign(this.value - anotherInteger.valuel); }