Почему 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())
Итак, эти две переменные имеют целочисленный тип.
Ответы
Ответ 1
Объекты (например, Integer
s) не должны сравниваться через ==
, а через .equals()
.
Важно понимать, что несколько различных объектов Integer
могут представлять одно и то же значение int. Когда ваша программа печатает >>> different
, она просто говорит, что первый объект не является тем же объектом, что и второй объект. (Хотя вы, вероятно, хотите сравнить объекты на основе того, какое значение они представляют.)
В официальном руководстве по автобоксингу:
[...] Оператор == выполняет сравнения ссылочной идентичности по выражениям Integer и сравнениям значений равенства по выражениям int. [...]
Возможно, стоит отметить, что автооблок гарантированно возвращает один и тот же объект для целых значений в диапазоне [-128, 127], но реализация может по своему усмотрению хранить значения кэша вне этого диапазона.
Моя общая рекомендация - использовать int
вместо Integer
для всех переменных local/member. В этом конкретном случае вы, кажется, сохраняете координаты в массиве из 2 элементов. Я бы предположил, что вы инкапсулируете это в класс Coordinates
или аналогичный и переопределите метод equals (и hashCode) здесь.
См. также
Ответ 2
Если бы они были простыми типами int
, это сработало бы.
В Integer
используйте .intValue()
или compareTo(Object other)
или equals(Object other)
в вашем сравнении.
Ответ 3
Здесь различают два типа:
-
int
, тип примитивного целого типа, который вы используете большую часть времени, но не тип объекта
-
Integer
, обертка объекта вокруг int
, которая может использоваться для использования целых чисел в API, для которых требуются объекты
Ответ 4
В java числовые значения в диапазоне от -128 до 127 кэшируются, поэтому, если вы попытаетесь сравнить
Integer i=12 ;
Integer j=12 ; // j is pointing to same object as i do.
if(i==j)
print "true";
это сработает, но если вы попробуете с числами из приведенного выше диапазона, их нужно сравнить с методом equals для сравнения значений, потому что "==" проверяет, являются ли оба одинакового объекта не одинаковыми.
Ответ 5
когда вы пытаетесь сравнить два объекта (и Integer - это объект, а не переменная), результат всегда будет равен тому, что они не равны,
в вашем случае вы должны сравнить поля объектов (в этом случае intValue)
попробуйте объявить переменные int вместо объектов Integer, это поможет
Ответ 6
Условие при
pay[0]==point[0]
использует оператор равенства == для сравнения ссылки
Integer pay[0]
для равенства с ссылкой
Integer point[0]
В общем случае, когда значения примитивного типа (такие как int,...) сравниваются с ==, результат верен, если оба значения идентичны. Когда ссылки (такие как Integer, String,...) сравниваются с ==, результат верен, если обе ссылки относятся к одному и тому же объекту в памяти.
Чтобы сравнить фактическое содержимое (или информацию состояния) объектов для равенства, необходимо вызвать метод.
Таким образом, при этом
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
потому что оба они являются значениями примитивного типа.
Для сравнения a с c используйте:
a == c
из-за функции автоматического бокса.
для сравнения c с использованием e:
c.equals(e)
из-за новой ссылки в переменной e.
для сравнения c с d лучше и безопаснее использовать:
c.equals(d)
из-за:
Как вы знаете, оператор ==, применяемый к объектам-оболочкам, проверяет, имеют ли объекты одинаковые ячейки памяти. Поэтому, вероятно, произойдет следующее сравнение:
Integer a = 1000;
Integer b = 1000;
if (a == b) . . .
Однако реализация Java может, если она выбирает, обертывать часто встречающиеся значения в идентичные объекты, и, таким образом, сравнение может быть успешным. Эта двусмысленность - это не то, что вы хотите. Средством является вызов метода equals при сравнении объектов-оболочек.