Descubrí que la java.lang.Integerimplementación del compareTométodo se ve de la siguiente manera:
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
La pregunta es por qué usar la comparación en lugar de la resta:
return thisVal - anotherVal;
java
optimization
integer
comparison
integer-overflow
Vladimir
fuente
fuente

Integer.compare(thisVal, anotherVal)lugar de escribir la expresión ternaria.Respuestas:
Esto se debe al desbordamiento de enteros. Cuando
thisVales muy grande yanotherVales negativo, restar el último del primero da un resultado que es mayor que elthisValque puede desbordar al rango negativo.fuente
thisValno necesita ser grande.thisValpodría ser incluso cero yanotherValserInteger.MIN_VALUEy ya tiene un desbordamiento. Y tenga en cuenta que, por supuesto, también podría ser al revés,thisValuemuy pequeño yanotherValbastante grande, para tener una distancia que desborde elintrango de valores.El "truco" de la resta para comparar dos valores numéricos está roto !!!
int a = -2000000000; int b = 2000000000; System.out.println(a - b); // prints "294967296"Aquí,
a < btodavíaa - bes positivo.NO use este modismo. No funciona.
Además, incluso si funciona , NO proporcionará ninguna mejora significativa en el rendimiento y, de hecho, puede costar la legibilidad.
Ver también
fuente
((long)a - b)debería funcionar. Aunque tienes razón; rara vez es útil.((long)a - b)no ayuda, ya que tienes que devolver el resultado aint, ya que eso es lo que el comparador tiene que devolver, terminando nuevamente con un desbordamiento. Tendría que hacer algo comoLong.signumen el resultado, que es fácil de olvidar, como muestra su comentario. Y puede que ni siquiera sea más eficiente queInteger.compare, lo que la JVM podría manejar intrínsecamente…Simplemente hablando, el
inttipo no es lo suficientemente grande para almacenar la diferencia entre dosintvalores arbitrarios . Por ejemplo, la diferencia entre 1.500 millones y -1.500 millones es de 3.000 millones, perointno puede contener valores superiores a 2.100 millones.fuente
Quizás sea para evitar desbordes / subdesbordamientos.
fuente
Además del desbordamiento, debes tener en cuenta que la versión con sustracción no da los mismos resultados .
Si sabe que no habrá desbordamiento, puede usar algo como esto:
public int compareTo(Integer anotherInteger) { return sign(this.value - anotherInteger.valuel); }fuente
compareTosolo se requiere para devolver un valor negativo, cero o un valor positivo, según el orden de clasificación dethisy el otro objeto. Ver java.sun.com/j2se/1.5.0/docs/api/java/lang/…