La comparación de caracteres, enteros y tipos similares en Java: Uso iguala o ==?

StackOverflow https://stackoverflow.com/questions/735832

  •  09-09-2019
  •  | 
  •  

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.

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:

  1. todos los valores implicados en la comparación son tipos primitivos (y preferiblemente no números de punto flotante)
  2. que realmente quiere saber si dos referencias se refieren al mismo objeto (esto incluye la comparación de enums, 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top