Почему Java не видит, что целые числа равны?
У меня есть целые числа, которые должны быть равны (и я проверяю это по выходным данным). Но по моему if
условие Java не видит, чтобы эти переменные имели одинаковое значение.
У меня есть следующий код:
if (pay[0]==point[0] && pay[1]==point[1]) {
game.log.fine(">>>>>> the same");
} else {
game.log.fine(">>>>>> different");
}
game.log.fine("Compare:" + pay[0] + "," + pay[1] + " -> " + point[0] + "," + point[1]);
И это производит следующий вывод:
FINE: >>>>>> different
FINE: Compare:: 60,145 -> 60,145
Вероятно, я должен добавить, что point
определяется так:
Integer[] point = new Integer[2];
а также pay
нас взяли из цикла-конструктора:
for (Integer[] pay : payoffs2exchanges.keySet())
Итак, обе эти переменные имеют целочисленный тип.
6 ответов
Объекты (такие как Integer
s) не следует сравнивать через ==
, но через .equals()
,
Важно понимать, что несколько разных Integer
объекты могут представлять одно и то же значение типа int. Когда ваша программа печатает >>> different
это просто говорит о том, что первый объект не является тем же объектом, что и второй объект. (Хотя вы, вероятно, хотите сравнить объекты на основе значения, которое они представляют.)
Из официального руководства по автобоксу:
[...] Оператор == выполняет сравнения ссылочных идентификаторов в выражениях Integer и сравнения равенств значений в выражениях int. [...]
Возможно, стоит отметить, что автобокс гарантированно возвращает один и тот же объект для целочисленных значений в диапазоне [-128, 127], но реализация может по своему усмотрению кэшировать значения за пределами этого диапазона.
Моя общая рекомендация заключается в использовании int
вместо Integer
для всех локальных / членских переменных. В этом конкретном случае вы, кажется, храните координаты в массиве из 2 элементов. Я хотел бы предложить вам заключить это в Coordinates
class или аналогичный и переопределите метод equals (и hashCode) здесь.
Смотрите также
Если бы они были простыми int
типы, это будет работать.
За Integer
использование .intValue()
или же compareTo(Object other)
или же equals(Object other)
в вашем сравнении.
В Java числовые значения в диапазоне от -128 до 127 кэшируются, поэтому, если вы попытаетесь сравнить
Integer i=12 ;
Integer j=12 ; // j is pointing to same object as i do.
if(i==j)
print "true";
это будет работать, но если вы попробуете с числами из приведенного выше диапазона значений, их нужно сравнить с методом равно для сравнения значений, потому что "==" проверит, являются ли оба объекта одним и тем же значением, а не одним и тем же
Здесь можно выделить два типа:
int
, примитивный целочисленный тип, который вы используете большую часть времени, но не тип объектаInteger
обертка объекта вокругint
который может быть использован для использования целых чисел в API, которые требуют объектов
При попытке сравнить два объекта (а целое число - это объект, а не переменная), результатом всегда будет то, что они не равны,
в вашем случае вы должны сравнить поля объектов (в этом случае intValue)
попробуйте объявить переменные типа int вместо объектов Integer, это поможет
Состояние при
pay[0]==point[0]
выражение, использует оператор равенства == для сравнения ссылки
Integer pay[0]
для равенства со ссылкой
Integer point[0]
В общем случае, когда значения примитивного типа (например, int, ...) сравниваются с ==, результат равен true, если оба значения идентичны. Когда ссылки (такие как Integer, String, ...) сравниваются с ==, результат равен true, если обе ссылки ссылаются на один и тот же объект в памяти. Чтобы сравнить фактическое содержимое (или информацию о состоянии) объектов на равенство, необходимо вызвать метод. Таким образом, с этим
Integer[] point = new Integer[2];
Выражение вы создаете новый объект, который получил новую ссылку и назначить его для точечной переменной.
Например:
int a = 1;
int b = 1;
Integer c = 1;
Integer d = 1;
Integer e = new Integer(1);
Для сравнения a с b используйте:
a == b
потому что оба они являются значениями примитивного типа.
Для сравнения с помощью c:
a == c
из-за функции автобокса.
Для сравнения с использованием:
c.equals(e)
из-за новой ссылки в переменной e.
для сравнения c с d лучше и безопаснее использовать:
c.equals(d)
потому что:
Как вы знаете, оператор ==, применяемый к объектам-оберткам, только проверяет, имеют ли объекты идентичные области памяти. Следовательно, следующее сравнение, вероятно, потерпит неудачу:
Integer a = 1000;
Integer b = 1000;
if (a == b) . . .
Однако реализация Java может, если она выберет, обернуть часто встречающиеся значения в идентичные объекты, и, таким образом, сравнение может быть успешным. Эта двусмысленность не то, что вы хотите. Решение проблемы - вызвать метод equals при сравнении объектов-оболочек.