Java Integer compareTo () - зачем использовать сравнение против вычитания?
Я нашел это 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;
5 ответов:
Это связано с переполнением целого числа. Когда
thisValочень большой иanotherValотрицательно, то вычитание последнего из первого дает результат, который больше, чемthisValкоторый может переполниться в отрицательный диапазон.
вычитание "трюк" для сравнения двух числовых значений нарушается!!!
int a = -2000000000; int b = 2000000000; System.out.println(a - b); // prints "294967296"здесь
a < b, ещеa - bположительный.не используйте эту идиому. Это не работает.
кроме того, даже если он работает, это не обеспечьте любое значительное улучшение в представлении, и смогите на самом деле стоить удобочитаемость.
см. также
- Java Загадки головоломка 65: странная сага подозрительного рода
Эта головоломка имеет несколько уроков. Наиболее конкретным является:не используйте компаратор на основе вычитания, если вы не уверены, что разница между значениями никогда не будет больше, чем
Integer.MAX_VALUE. В более общем плане, остерегайтесьintпереполнения. Еще один урок заключается в том, что вы должны избегать "умный" код. Стремитесь писать четкий, правильный код, и не оптимизируйте его, если это не доказывает необходимый.
проще говоря,
intтип не достаточно большой, чтобы хранить разницу между двумя произвольнымиintзначения. Например, разница между 1,5 млрд и 1,5 млрд составляет 3,0 млрд, ноintне может содержать значения больше 2,1 миллиарда.
в дополнение к переполнению вещи, вы должны отметить, что версия с вычитанием не дает тех же результатов.
- первая версия compareTo возвращает одно из трех возможных значений: -1, 0 или 1.
- если вы замените последнюю строку вычитанием, результатом может быть любое целое значение.
Если вы знаете, что не будет переполнения, вы можете использовать что-то вроде этого:
public int compareTo(Integer anotherInteger) { return sign(this.value - anotherInteger.valuel); }
Comments