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