Cuando se comparan dos enteros iguales en el bucle while, el operador equal-to falla?

He publicado dos ejemplos a continuación.

En el primer ejemplo, utilizo el operador equal-to y el proceso while continúa para siempre en vez de romperse cuando debería.

En el segundo ejemplo, utilizo el operador mayor-o-igual-a , y el proceso se rompe cuando debería.

Como es esto posible?

EJEMPLO 1:

Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2 == myVar1) { break; } ++ myVar2; } 

EJEMPLO 2:

  Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2 >= myVar1) { break; } ++ myVar2; } 

EDIT: Gracias a todos por las grandes respuestas! Entiendo completamente el problema ahora y esta nueva información explicó varios comportamientos extraños que he encontrado en mis aplicaciones. Ojalá pudiera elegir más de una mejor respuesta.

Este es uno de los efectos menos agradables del auto-boxeo.

En su primer ejemplo, el operador == indica igualdad de identidad: los dos objetos sólo serán iguales si son la misma instancia.

En su segundo ejemplo, el operador '> =' indica la comparación numérica: los dos objetos se auto-unboxed y luego se comparan.

Haciendo las cosas más confusas, hay un rango de "pequeños" enteros (-128 <= X <= 127, iirc) para los que la JVM almacena valores Integer , por lo que el operador == veces funciona.

En resumen: use .equals() y .compareTo() .

Usted querrá usar .equals() para comparar el valor de dos objetos.

Cada vez que uses == compararás instancias de objetos. .equals() es un método heredado de Object y se utiliza para comparar los valores de objetos.

>= no funciona con objetos, sólo números. Los números ints se desacoplan en entradas que se pueden comparar correctamente.

Cuando se utiliza == no se produce unboxing y, por tanto, se comparan las referencias. Esto nunca se garantiza para comparar los valores.

Puedes usar:

 (myVar2.equals(myVar1)) 

En el EJEMPLO 1, cuando se utiliza el operador == con dos Integer se están comparando sus posiciones en la memoria, ya que Integer es una clase y las variables myVar1 y myVar2 son objetos y no se descartan en dos primitivas, mientras que en el Ejemplo 2 , cuando se utiliza el operador >= los dos objetos Integer se eliminan y el proceso se rompe cuando debería. Puede utilizar el operador equals :

 Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2.equals(myVar1)) { break; } ++myVar2; } 

O puede intentar el método intValue() :

 Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2.intValue() == myVar1.intValue()) { break; } ++myVar2; } 

Si un valor de objeto Integer es igual o menor que 127 el operador == funcionará:

 Integer myVar1 = 127; Integer myVar2 = 1; while (true) { if (myVar2 == myVar1) { break; } ++myVar2; } 

Tienes que usar equals cuando compares 2 objetos.

si todavía quieres usar >= entonces auto-unbox (de-autobox) myvar1 y myvar2 :

 if (myVar2.intValue() >= myVar1.intValue()) 

Una sencilla práctica recomendada para el auto-boxing en Java: Las clases de wrapper sólo deben utilizarse siempre que no se pueda usar una primitiva.

Autounboxing se produce cuando se utiliza el >= pero no cuando se compara con == uso equals para comparar los objetos

Te recomiendo que compruebes esta pregunta

Utilice este código para comparar:

  Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2.equals(myVar1)) { break; } ++ myVar2; } 

Estás comparando si las referencias son las mismas aquí, no estás comparando tipos primitivos:

 if (myVar2 == myVar1) 

Debe utilizar equals para comparar los valores:

 if (myVar2.equals( myVar1 ) ) 

Para el caso >= , esto no funcionará con un Object para deshacer los valores y trabajar como se espera.

En Java, el tipo 'int' es un primitivo, mientras que el tipo 'Integer' es un objeto.

así que para comparar los objetos use el método del igual ()

así que utilice:

  Integer myVar1 = 42985; Integer myVar2 = 1; while (true) { if (myVar2.equals(myVar1)) { break; } ++ myVar2; } 

o declararlo utilizando int

 int myVar1 = 42985; int myVar2 = 1; while (true) { if (myVar1==myVar2) { break; } ++ myVar2; } 
  • ¿Soporte de Enums con Realm?
  • Cómo obtener un error en Android Studio 2.1 con java 8
  • Alertdialog.Builder setview: la llamada requiere el nivel 21 de la API
  • Descifrado AES en Android demasiado lento para ser utilizable. ¿NDK será más rápido? ¿Otras ideas?
  • Onclick evento en textview (que tiene TextIsSelectable = "true") es ony llamado en segundo clic
  • Descartar actividad en android
  • A veces, Logcat muestra que "GREF ha aumentado a 301"
  • Compara las fechas con Parse.com
  • UnsatisfiedLinkError (Método nativo no encontrado)
  • Android crear ID de forma programática
  • Utilizar interfaces para constantes de espacio de nombres en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.