2012-02-23 21 views
5

Se due String s non sono identici, perché utilizzare le stringhe come chiavi in ​​un HashMap senza utilizzare lo stesso oggetto String?Perché posso utilizzare le stringhe come chiavi in ​​una 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? 

Fa HashMap hanno qualche comportamento speciale per String oggetti? In caso contrario, perché è possibile utilizzare due stringhe "diverse" per inserire e ottenere valori da un hash?

+6

Si noti che 's1 == s2' sarà' true' a causa dell'internamento della stringa. –

+0

Allora perché è pratica normale usare '.equals()' per confrontare 'String's? –

+1

@Ted Hopp s1 == s2 sarà vero a causa del * pooling costante *. – EJP

risposta

14

HashMap confronta gli oggetti chiamando equals() e hashCode().
String esegue l'override di questi metodi per confrontare per valore.

4

Se due stringhe che sono gli stessi, non sono in realtà uguali

Ma sono. Sono uguali sotto il metodo equals() e questa è la tecnica specificata per il test di uguaglianza nell'interfaccia Map.

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

Ma non è falso! Entrambi si riferiscono alla stessa stringa a causa del costante raggruppamento da parte del compilatore.

2

Quando lo HashMap confronta la chiave internamente, utilizza il metodo equals(), non ==. Quindi oggetto l'uguaglianza va bene per una partita chiave, la parità di riferimento non è necessaria se equals() viene sostituita (come nel caso di java.lang.String.)

5

In generale, è possibile utilizzare oggetti String perché HashMap utilizza equals() e non == per verificare uguaglianza chiave.

1

System.out.println (s1 == s2); // dovrebbe essere falso

Non dovrebbe. Il compilatore Java può ottimizzare e puntare due stringhe nella stessa posizione.

Aggiornamento

public class Test { 

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

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

} 

uscita

javac Test.java 
java Test 
> true 
+0

Sbagliato, sbagliato, sbagliato. Puoi facilmente provarlo con un codice semplice. – duffymo

+3

No, non è sbagliato. Si chiama "interning". –

+2

Con "può ottimizzare", penso che tu intenda "deve ottimizzare", supponendo che il compilatore Java sia all'altezza delle specifiche. http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 – yshavit

-2

dovremmo davvero andare indietro alla prima base. scienza

calcolatore fondamentale:

== confronta l'indirizzo di memoria (di riferimento)

.equals confronta valore memorizzato nell'indirizzo di memoria

java di base. c'è solo una copia dell'oggetto stringa sull'intera jvm

+3

Quasi ogni riga della risposta è sottilmente o apertamente errata – SLaks

+0

Questi non sono "fondamenti dell'informatica". Sono fondamentali di * Java *. Un riferimento Java non è necessariamente un indirizzo di memoria. Possono esserci più copie di una stringa se si utilizza la costruzione 'new String (...)'. – EJP

Problemi correlati