我发现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;
答案 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 也会提供性能上的任何重大改进,实际上可能会带来成本可读性。
这个谜题有几个教训。最具体的是:除非您确定值之间的差异永远不会大于
Integer.MAX_VALUE
,否则不要使用基于减法的比较器。更一般地说,要小心int
溢出。另一个教训是你应该避免“聪明”的代码。努力编写清晰,正确的代码,除非证明有必要,否则不要对其进行优化。
答案 2 :(得分:9)
简单来说,int
类型不足以存储两个任意int
值之间的差异。例如,15亿和-1.5亿之间的差异是30亿,但int
不能超过21亿。
答案 3 :(得分:3)
也许是为了避免溢出/下溢。
答案 4 :(得分:1)
除了溢出之外,你应该注意带有减法的版本不会给出相同的结果。
如果你知道没有溢出,你可以使用这样的东西:
public int compareTo(Integer anotherInteger) {
return sign(this.value - anotherInteger.valuel);
}