2012-01-23 6 views
39

Diciamo che ho questo codice in Java:Un'idoneità di test del metodo() di hash di Java HashSet <String> contiene le stringhe o l'identità dell'oggetto?

HashSet<String> wordSet = new HashSet<String>(); 
String a = "hello"; 
String b = "hello"; 
wordSet.add(a); 

Would wordSet.contains(b); ritorno true o false? Da quello che ho capito, a e b si riferiscono a oggetti diversi anche se i loro valori sono gli stessi. Quindi dovrebbe restituire false. Tuttavia, quando eseguo questo codice, restituisce true. Restituisce sempre true indipendentemente da dove l'oggetto stringa b provenga finchè b contiene il valore "hello"? Sono sempre garantito questo? Se no, quando non sono garantito questo? E se volessi fare qualcosa di simile con oggetti diversi dalle stringhe?

risposta

46

Usa equals() per confrontare i dati. Sotto è dal javadoc for Set

aggiunge l'elemento e specificato a questo insieme se il set non contiene e2 elemento tale che (e == null e2 == null: e.equals (e2)).

Il metodo equals() per String esegue un confronto carattere per carattere. Dal javadoc for String

Il risultato è vero se e solo se l'argomento non è nullo ed è un oggetto String che rappresenta la stessa sequenza di caratteri dell'oggetto

3

In realtà, sia a che b si riferiscono allo stesso oggetto, poiché le stringhe letterali in Java vengono automaticamente internate.

+0

... ed è per questo che lui/lei ha detto 'Sarà tornare sempre vero, non importa dove String oggetto b è venuta da fintanto che B contiene il valore 'ciao'?' –

+0

'Da quanto ho capito, a e b si riferiscono a oggetti diversi anche se i loro valori sono gli stessi. - Sono abbastanza sicuro che non è quello che pensava. – Perception

+0

Sì, mi dispiace, hai ragione. In ogni caso, la domanda che gli veniva posta era se gli HashSet usassero l'uguaglianza o l'identità; è solo il suo esempio che è un tantino imperfetto. –

0

Uguaglianza. Nell'esempio, restituisce true, poiché HashSet controlla a.equals(b).

3

due cose:

  1. Un set sarebbe piuttosto inutile a meno che non si chiamasse il metodo equals() per determinare l'uguaglianza. wordset.contains (b) restituirà true perché a.equals (b) == true.

  2. Non si può essere completamente sicuri che a e b puntino a oggetti diversi. Checkout String.intern() per maggiori dettagli.

6

In realtà, HashSet fa .

sua attuazione utilizza un HashMap, e qui è il codice corrispondente che determina se il (metodo in realtà è dentro getEntry di HashMap()) serie:

if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) 

cui:

  • richiede gli hash uguale, e
  • richiede o uguaglianza oggetto o equals() restituisce true

la risposta è "sì": wordSet.contains(b) sarà sempre tornare true

+1

L'OP ha chiesto informazioni su 'HashSet '. Il metodo 'hashCode' della' String' classe restituisce valori uguali per due stringhe per cui 'equals' è vero. Il metodo 'equestre' della' String' restituisce true se il suo argomento è lo stesso oggetto dell'oggetto per cui è chiamato. Quindi la condizione che hai citato è logicamente equivalente a 'equals()'. –

1

definitiva contains verifica la presenza di equals metodo piuttosto che la sua validazione id oggetto per contiene il metodo. Quindi il metodo equals verrà chiamato per la chiamata contains. Questa è la struttura della chiamata del metodo contains.

private transient HashMap<E,Object> map; 
    public boolean contains(Object o) { 
    return map.containsKey(o); 
    } 


    public boolean containsKey(Object key) { 
     return getEntry(key) != null; 
    } 


    final Entry<K,V> getEntry(Object key) { 
     int hash = (key == null) ? 0 : hash(key.hashCode()); 
     for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
      e != null; 
      e = e.next) { 
      Object k; 
      if (e.hash == hash && 
       ((k = e.key) == key || (key != null && key.equals(k)))) 
       return e; 
     } 
     return null; 
    } 
+0

E lo stesso vale per HashSet? – OkonX

+0

Sì, per 'HashSet' verrà chiamato anche il metodo' equals' per 'contains' –