Почему Java не видит, что целые числа равны? - PullRequest
22 голосов
/ 13 декабря 2010

У меня есть целые числа, которые должны быть равны (и я проверяю это по выводу). Но в моем 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 us взяты из конструктора цикла:

for (Integer[] pay : payoffs2exchanges.keySet())

Итак, обе эти переменные имеют целочисленный тип.

Ответы [ 6 ]

54 голосов
/ 13 декабря 2010

Объекты (такие как Integer s) должны сравниваться не через ==, а через .equals().

Важно понимать, что несколько различных Integer объектов могут представлять одно и то же значение типа int. Когда ваша программа печатает >>> different, она просто говорит, что первый объект не является тем же объектом , что и второй объект. (Хотя вы, вероятно, хотите сравнить объекты на основе значения, которое они представляют.)

Из официального руководства по автобоксу:

[...] Оператор == выполняет сравнения ссылочных идентификаторов в выражениях Integer и сравнения равенств значений в выражениях int. [...]

Возможно, стоит отметить, что автобокс гарантированно возвращает тот же объект для целочисленных значений в диапазоне [-128, 127], но реализация может по своему усмотрению кэшировать значения вне этого диапазона.

Моя общая рекомендация - использовать int вместо Integer для всех локальных переменных / переменных-членов. В этом конкретном случае вы, кажется, храните координаты в массиве из 2 элементов. Я бы посоветовал вам инкапсулировать это в класс Coordinates или аналогичный и переопределить здесь метод equals (и hashCode).

Смотри также

12 голосов
/ 13 декабря 2010

Если бы это были простые int типы, это сработало бы.

Для Integer используйте .intValue() или compareTo(Object other) или equals(Object other) в вашем сравнении.

4 голосов
/ 13 декабря 2010

Здесь можно различить два типа:

  • int, примитивный целочисленный тип, который вы используете большую часть времени, но не тип объекта
  • Integer, обертка объекта вокруг int, которая может использоваться для использования целых чисел в API, для которых требуются объекты
2 голосов
/ 31 августа 2015

В java числовые значения в диапазоне от -128 до 127 кэшируются, поэтому, если вы попытаетесь сравнить

Integer i=12 ;
Integer j=12 ; // j is pointing to same object as i do.
if(i==j)
   print "true";

это будет работать, но если вы попробуете с числами из приведенного выше диапазона значений, их нужно сравнить с методом равенства для сравнения значений, потому что "==" проверит, являются ли оба объекта одним и тем же значением, а не значением.

1 голос
/ 13 декабря 2010

при попытке сравнить два объекта (а целое число - это объект, а не переменная), результатом всегда будет то, что они не равны,

в вашем случае вы должны сравнить поля объектов (в данном случае intValue)

попробуйте объявить переменные типа int вместо объектов Integer, это поможет

0 голосов
/ 30 октября 2016

Состояние при

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 использованием e:

c.equals(e)

из-за новой ссылки в переменной e.

для сравнения c с d лучше и безопаснее использовать:

  c.equals(d)

из-за:

Как вы знаете, оператор ==, применяемый к объектам-оберткам, только проверяет, имеют ли объекты идентичные области памяти. Следовательно, следующее сравнение, вероятно, потерпит неудачу:

Integer a = 1000;
Integer b = 1000;
if (a == b) . . .

Однако реализация Java может, если она выберет, обернуть часто встречающиеся значения в идентичные объекты, и, таким образом, сравнение может быть успешным. Эта двусмысленность не то, что вы хотите. Решение проблемы - вызвать метод equals при сравнении объектов-оболочек.

...