Почему 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 при сравнении объектов-оболочек.

Другие вопросы по тегам