2012-02-23 23 views
5

Si dos String s que son iguales no son realmente idénticos, entonces ¿por qué puedo usar cadenas como claves en un HashMap sin usar el mismo objeto String?¿Por qué puedo usar cadenas como claves en un HashMap?

String s1 = "Test"; 
String s2 = "Test"; 

System.out.println(s1 == s2); // should be false 
System.out.println(s1.equals(s2)); // should be true 

HashMap<String, String> map = new HashMap(); 
map.put(s1, "foo"); 
System.out.println(map.get(s2)); // should be "foo"--but why? 

¿Tiene HashMap tienen algún comportamiento especial para String objetos? Si no, ¿por qué se pueden usar dos cadenas "diferentes" para poner y obtener valores de un hash?

+6

Tenga en cuenta que 's1 == s2' será' verdadero' debido a la cadena interna. –

+0

Entonces, ¿por qué es una práctica estándar usar '.equals()' para comparar 'String's? –

+1

@Ted Hopp s1 == s2 será verdadero debido a * agrupamiento constante *. – EJP

Respuesta

14

HashMap compara objetos llamando al equals() y hashCode().
String anula estos métodos para comparar por valor.

4

Si dos cadenas que son los mismos en realidad no son iguales

Pero son. Son iguales bajo el método equals(), y esa es la técnica especificada para la prueba de igualdad en la interfaz Map.

System.out.println(s1 == s2); // should be false 

Pero no es falso! Ambos se refieren a la misma cadena debido a la agrupación constante por parte del compilador.

2

Cuando el HashMap compara la clave interna, se utiliza el método equals(), no ==. Así objeto la igualdad está muy bien para un partido clave, no es necesaria la igualdad de referencia si equals() se anulados (como en el caso de java.lang.String.)

5

En general, puede utilizar objetos String porque HashMap utiliza equals() y no == para probar igualdad clave

1

System.out.println (s1 == s2); // debería ser falso

No debería. El compilador Java puede optimizar y señalar dos cadenas a la misma ubicación.

actualización

public class Test { 

    public static void main(String... args) { 
     String s1 = "abc"; 
     String s2 = "abc"; 

     System.out.println(s1 == s2); 
    } 

} 

salida

javac Test.java 
java Test 
> true 
+0

Incorrecto, incorrecto, incorrecto. Puedes demostrarlo fácilmente con un código simple. – duffymo

+3

No, no está mal. Se llama "internamiento". –

+2

Por "puede optimizar", creo que quiere decir "debe optimizar", suponiendo que el compilador de Java cumple con las especificaciones. http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 – yshavit

-2

que realmente deberíamos volver a la primera base. ciencia

el equipo fundamental:

== compara dirección de memoria (referencia)

.equals compara el valor almacenado en la dirección de memoria

java básico. solo hay una copia de un objeto de cadena en todo el jvm

+3

Casi todas las líneas de su respuesta son sutilmente o descaradamente erróneas – SLaks

+0

No se trata de "fundamentos de la informática". Son * fundamentos de Java *. Una referencia de Java no es necesariamente una dirección de memoria. Puede haber múltiples copias de una cadena si usa la construcción 'new String (...)'. – EJP

Cuestiones relacionadas