¿Por qué Java no ve que los enteros son iguales?

Tengo enteros que se supone que son iguales (y lo verifico por salida). Pero en mi condición if , Java no ve estas variables para tener el mismo valor.

Tengo el siguiente código:

 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]); 

Y produce el siguiente resultado:

 FINE: >>>>>> different FINE: Compare:: 60,145 -> 60,145 

Probablemente debo agregar que ese point se define así:

 Integer[] point = new Integer[2]; 

y nos pay tomado del constructor de bucles:

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

Entonces, estas dos variables tienen el tipo entero.

Los objetos (como los Integer ) no se deben comparar mediante == , sino a través de .equals() .

Lo que es importante entender es que varios objetos Integer diferentes pueden representar el mismo valor int. Cuando su progtwig imprime >>> different , simplemente dice que el primer objeto no es el mismo objeto que el segundo. (Si bien es probable que desee comparar los objetos según el valor que representan).

De la guía oficial sobre autoboxing:

[…] El operador == realiza comparaciones de identidad de referencia en expresiones de enteros y comparaciones de valores de igualdad en expresiones int. […]

Puede valer la pena señalar que se garantiza que el autoboxing devuelve el mismo objeto para valores integrales en el rango [-128, 127], pero una implementación puede, a su discreción, valores de caché fuera de ese rango.

Mi recomendación general es usar int lugar de Integer para todas las variables locales / miembros. En este caso particular parece que almacena coordenadas en una matriz de 2 elementos. Sugeriría encapsular esto en una clase Coordinates o similar y anular el método equals (y hashCode) aquí.

Ver también

  • Introducción al autoboxing
  • Errores de autoboxing al comparar números con “==”

Si fueran tipos int simples, funcionaría.

Para Integer use .intValue() o compareTo(Object other) o sea equals(Object other) en su comparación.

Hay dos tipos para distinguir aquí:

  • int , el tipo de entero primitivo que usa la mayor parte del tiempo, pero no es un tipo de objeto
  • Integer , un contenedor de objetos alrededor de un int que se puede usar para usar enteros en las API que requieren objetos

En java, los valores numéricos dentro del rango de -128 a 127 se almacenan en caché, por lo que si intentas comparar

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

esto funcionaría, pero si lo intentas con números del rango de distribución anterior, debes compararlos con el método de igualdad para la comparación de valores porque “==” comprobará si ambos son el mismo objeto y no el mismo valor.

cuando intenta comparar dos objetos (y un entero es un objeto, no una variable), el resultado siempre será que no son iguales,

En su caso, debe comparar los campos de los objetos (en este caso intValue)

intente declarar variables int en lugar de objetos enteros, ayudará

La condición en

 pay[0]==point[0] 

expresión, utiliza el operador de igualdad == para comparar una referencia

 Integer pay[0] 

por la igualdad con la referencia a

 Integer point[0] 

En general, cuando los valores de tipo primitivo (como int, …) se comparan con ==, el resultado es verdadero si ambos valores son idénticos. Cuando las referencias (como Integer, String, …) se comparan con ==, el resultado es verdadero si ambas referencias se refieren al mismo objeto en la memoria. Para comparar los contenidos reales (o la información de estado) de los objetos para la igualdad, se debe invocar un método. Por lo tanto, con esto

 Integer[] point = new Integer[2]; 

expresión crea un nuevo objeto que tiene nueva referencia y lo asigna a la variable de punto.

Por ejemplo:

 int a = 1; int b = 1; Integer c = 1; Integer d = 1; Integer e = new Integer(1); 

Para comparar un uso con b:

 a == b 

porque ambos son valores de tipo primitivo.

Para comparar a c con el uso:

 a == c 

debido a la función de auto-boxing.

para comparar c con e use:

 c.equals(e) 

debido a una nueva referencia en la variable e.

para comparar c con d, es mejor y seguro de usar:

  c.equals(d) 

porque:

Como usted sabe, el operador ==, aplicado a objetos envoltura, solo prueba si los objetos tienen ubicaciones de memoria idénticas. Por lo tanto, la siguiente comparación probablemente fallaría:

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

Sin embargo, una implementación de Java puede, si lo desea, ajustar los valores que ocurren comúnmente en objetos idénticos y, por lo tanto, la comparación puede tener éxito. Esta ambigüedad no es lo que quieres. El remedio es llamar al método equals cuando se comparan objetos wrapper.