2010-12-13 20 views
19

Tengo enteros que se supone que son iguales (y lo verifico por salida). Pero en mi condición if, Java no considera que estas variables tengan el mismo valor.¿Por qué Java no ve que los enteros son iguales?

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 producir el siguiente resultado:

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

Probablemente tengo que añadir que point se define así:

Integer[] point = new Integer[2]; 

y pay nosotros tomados del constructor de bucles:

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

Por lo tanto, estas dos variables tienen tanto el tipo entero.

+3

si tienes una mente abierta, entonces es posible que te guste mi explicación ... Es porque los creadores de Java realmente se equivocaron cuando decidieron hacer las clases contenedoras, que tienen un rendimiento realmente patético (no tienes idea sobre el desperdicio generado al envolver un * int * dentro de un * Entero *). Lo hicieron principalmente porque no pudieron diseñar algo limpio y eficiente como, por ejemplo, * Trove * 's * TLongIntHashMap *. Por supuesto, espere comentarios vertiginosos de la gente que bebió Java-aid explicando cómo estoy equivocado y cómo las clases de envoltura son una bendición del cielo;) – SyntaxT3rr0r

+1

por cierto, nunca haga un * nuevo Entero [2] * porque fuerza el creación de un nuevo objeto ** IFF ** sigues usando clases contenedoras como * Integer * (que realmente no deberías, pero ese es otro tema), quieres hacer un * Integer.valueOf (2) * (por cierto que luego uno ** garantiza ** según las especificaciones de Java, la reutilización de los primeros 256 objetos Integer de -128 a 127, pero ese no es un brainfart de Java muy conocido). – SyntaxT3rr0r

+0

SpoonBender: ¿Qué pasa con la decisión de los creadores de Java * de * permitir la sobrecarga del operador para las cadenas? De esa forma 'Integer.valueOf (127) == Integer.valueOf (127)' pero 'Integer.valueOf (128)! = Integer.valueOf (128)'! – Gabe

Respuesta

49

objetos (como Integer s) no deben ser comparados a través ==, sino a través de .equals().

Lo que es importante comprender es que varios objetos diferentes Integer pueden representar el mismo valor int. Cuando su programa imprime >>> different simplemente dice que el primer objeto no es el mismo objeto como el segundo objeto. (Si bien es probable que desee comparar los objetos de la base de que el valor que representan.)

Desde el official guide en autoboxing:

[...] El operador == realiza comparaciones de identidad de referencia en expresiones enteras y valorar las comparaciones de igualdad en expresiones int. [...]

Puede valer la pena señalar que autoboxing está garantizada para devolver el mismo objeto para valores enteros en el rango [-128, 127], sino una aplicación puede, a su discreción, los valores de caché fuera de ese rango.

Mi recomendación general es usar int en lugar de Integer para todas las variables/miembros locales. 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

9

Si fueran simples int tipos, que funcionaría.

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

4

Hay dos tipos de distinguir aquí:

  • int, el tipo entero primitiva que la mayoría de las veces se utiliza, pero no es un tipo de objeto
  • Integer, una envoltura objeto alrededor de un int cuales se puede usar para usar enteros en las API que requieren objetos
1

cuando intenta comparar dos objetos (y un entero es un objeto, no una variable) el resultado siempre será t ambién están no igual,

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

tratar la declaración de variables int en lugar de objetos Integer, que le ayudará

2

En valores numéricos java dentro del rango de -128 a 127 están en caché por lo que si se intenta comparar

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

esto iba a funcionar, pero si se intenta con los números fuera del rango de dar por encima de lo que necesitan para ser comparado con igual método para la comparación del valor debido "==" verificará si ambos son el mismo objeto no el mismo valor.

0

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

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 esta expresión

Integer[] point = new Integer[2]; 

se crea un nuevo objeto que tiene nueva referencia y asignarlo a señalar variable.

Por ejemplo:

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

para comparar una con b uso:

a == b 

porque ambos son valores de tipo primitivo.

para comparar una con el uso c:

a == c 

debido a la característica de auto-boxeo.

para comparar con el uso c e:

c.equals(e) 

debido a la nueva referencia en e variable.

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

c.equals(d) 

debido a:

Como saben, el operador ==, aplicado a objetos de envoltorio, sólo comprueba si los objetos tienen ubicaciones de memoria idénticas. La siguiente comparación sería por lo tanto probablemente fallará:

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

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

Cuestiones relacionadas