La comparación de caracteres, enteros y tipos similares en Java: Uso iguala o ==?
Pregunta
Yo quería hacer seguro de algo en Java: Si tengo un carácter o un número entero o una larga y ese tipo de cosas, debería usar es igual o == suficiente?
Sé que con cadenas que no hay garantías de que sólo hay una instancia de cada cadena única, pero no estoy seguro acerca de otros tipos de caja.
Mi intuición es usar iguales, pero quiero asegurarme de que no estoy perdiendo el rendimiento.
Solución
EDIT: La especificación hace algunos garantías para las conversiones de boxeo. De la sección rel="noreferrer"> href="http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7" :
Si el valor p de ser en caja es cierto, falso, un byte, un char en el rango \ U0000 a \ u007f, o un int o corto número entre -128 y 127, y luego dejar R1 y R2 sean los resultados de cualquiera de dos conversiones de boxeo de p. Es siempre el caso de que r1 r2 ==.
La aplicación puede utilizar una piscina más grande, claro está.
Me realmente evitar la escritura de código que se basa en que, aunque. No porque se puede producir un error, sino porque no es obvio - poca gente sabrá la especificación que también. (Anteriormente pensé que era dependiente de la implementación.)
Debe utilizar equals
o comparar los valores subyacentes, es decir.
if (foo.equals(bar))
o
if (foo.intValue() == bar.intValue())
Tenga en cuenta que incluso si el autoboxing se garantiza para utilizar valores fijos, siempre que los interlocutores pueden crear instancias separadas de todos modos.
Otros consejos
Si desea comparar nada sobre el valor de cualquier objeto, utiliza .equals()
.
Incluso (y especialmente) si esos objetos son los tipos de envoltura primitivas byte, carácter, Short, Integer, Long, Float, Double y booleanos.
"==
" solamente siempre compara la identidad de los objetos y que es muy, muy rara vez lo que desea. Y de facto no lo que quiera con las envolturas primitivas.
Sólo utilice ==
en uno de esos dos escenarios:
- todos los valores implicados en la comparación son tipos primitivos (y preferiblemente no números de punto flotante)
- que realmente quiere saber si dos referencias se refieren al mismo objeto (esto incluye la comparación de
enum
s, ya que el valor está ligado a la identidad del objeto)
//Quick test
public class Test {
public static void main(String[] args) {
System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
}
}
Salida:
"¿Son iguales? 0"
Respuesta:
No, no son iguales. Debe utilizar .equals o comparar sus valores primitivos.
del lenguaje Java Spec 5.1.7 :
Si el valor p de ser en caja es cierto, falso, un byte, un char en el rango \ U0000 a \ u007f, o un int o corto número entre -128 y 127, y luego dejar R1 y R2 sean los resultados de cualquiera de dos conversiones de boxeo de p. Es siempre el caso de que r1 r2 ==.
y
discusión
Lo ideal es que el boxeo un hecho primitivo valor p, siempre daría una referencia idénticos. En la práctica, esto puede no ser factible usando existente técnicas de implementación. Las normas anteriormente son un compromiso pragmático. los cláusula final anterior requiere que ciertos valores comunes siempre encasillarán en objetos indistinguibles. los aplicación puede almacenar en caché estos, perezosamente o con ansiedad.
Para otros valores, esta formulación desautoriza ninguna hipótesis sobre la la identidad de los valores en la caja parte del programador. Esto permitiría (Pero no requiere) intercambio de algunos o todas estas referencias.
Esto asegura que en el más común casos, el comportamiento será el deseada, sin imponer una indebida penalización de rendimiento, especialmente en pequeños dispositivos. Menos memoria limitada implementaciones podría, por ejemplo, almacenar en caché todos los caracteres y pantalones cortos, como así como los números enteros y largos en el gama de -32K -. + 32 K
Por lo tanto, en algunos casos == va a funcionar, en muchos otros no lo harán. Siempre use .equals ser seguro ya que no puede concesionario (en general) de cómo se obtuvieron los casos.
Si la velocidad es un factor (la mayoría de .equals comienzan con una comparación ==, o al menos deberían) y se puede gurantee forma en que fueron asignados y que encajan en los rangos anteriores, entonces == es seguro.
Algunas máquinas virtuales pueden aumentar este tamaño, pero es más seguro suponer el tamaño más pequeño según lo especificado por la especificación langauge que depender de un comportamiento particular VM, a menos que realmente realmente realmente necesita.
Las implementaciones del método equals (Object o) casi siempre comienzan con
if(this == o) return true;
por lo que usar equals
incluso si ==
es cierto no es realmente mucho de un impacto en el rendimiento.
Yo recomiendo siempre * utilizando el método equals
en los objetos.
* por supuesto, hay muy pocas ocasiones en las que no debe tomar este consejo.
La respuesta general es no , usted no está garantizado que para el mismo valor numérico, los objetos largos que recibe son los mismos (aunque se limite a usar Long.valueOf ()).
Sin embargo, es posible que se podrían obtener una mejora del rendimiento por primera tratando de probar la igualdad de las referencias (usando ==) y los iguales, entonces, si no, que tratan (). Todo depende de los costos comparativos de la prueba adicional == y el método llamado ... Su kilometraje puede variar, pero vale la pena intentar una prueba de bucle sencillo para ver cuál es mejor.
Es de destacar que los valores de auto-caja se agruparon usos objeto si están disponibles. Esta es la razón (entero) == 0 (entero) 0 pero (entero) 128! = (Entero) 128 para Java 6u13
Me gusta ver el resultado visual:
public static void main(String[] args)
{
Integer a = 126; //no boxed up conversion, new object ref
Integer b = 126; //no boxed up conversion, re-use memory address
System.out.println("Are they equal? " + (a == b)); // true
Integer a1 = 140; //boxed up conversion, new object
Integer b1 = 140; //boxed up conversion, new object
System.out.println("Are they equal? " + (a1 == b1)); // false
System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
}
==
compara la referencia de objeto mientras equals(Object obj)
compara por la igualdad objeto. Si alguna vez puede haber más de una instancia de un objeto es igual a la existencia , entonces debe equals
uso de comparación de igualdad.
Ejemplos:
Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);
Estos son diferentes instancias de objetos, pero son iguales de acuerdo a la igualdad de número entero, por lo que debe utilizar equals(Object obj)
public enum Gender {
MALE, FEMALE;
}
en este caso sólo habrá una instancia de FEMALE
en existencia así ==
es seguro de usar.