2015-07-17 34 views
6

Ho eseguito il codice seguente e ho trovato che l'output era false.HashSet contiene il metodo()

import java.util.Set; 
import java.util.HashSet; 

public class Name { 
    private String first, last; 

    public Name(String first, String last) { 
     this.first = first; 
     this.last = last; 
    } 

    public boolean equals(Object o) { 
     if (!(o instanceof Name)) 
      return false; 
     Name n = (Name) o; 
     return n.first.equals(first) && n.last.equals(last); 
    } 

    public static void main(String[] args) { 
     Set<Name> s = new HashSet<Name>(); 
     s.add(new Name("Donald", "Duck")); 
     System.out.println(s.contains(new Name("Donald", "Duck"))); 
    } 
} 

voglio sapere come si comporta e perché l'uscita è false.

+8

Non hai sovrascritto 'hashCode'. –

risposta

5

È necessario eseguire l'override del metodo hashCode() anche insieme a equals(). Entrambi i metodi sono utilizzati per una corretta funzionalità del HashSet, quindi devono essere sovrascritte in una classe definita dall'utente se si stanno facendo che class come key, altrimenti hashCode() di Object classe si sta abituando e non due diversi objects può essere considerato come come il hashCode() sarebbe sempre diverso, e sicuramente restituirà false sempre nel caso di .

+0

@babanna se ha chiarito i tuoi dubbi, puoi contrassegnarlo come corretto. Il formato di codice –

3

Al fine di un HashSet (o HashMap, se è per questo) per individuare correttamente l'oggetto, è necessario eseguire l'override del metodo hashCode() in modo che due oggetti che sono uguali hanno la stessa hashCode. Il modo canonico di fare questo assomiglia a questo (supponendo first e last non può essere null, come il metodo di equals assume:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + first.hashCode(); 
    result = prime * result + last.hashCode(); 
} 
1

Il tuo metodo equals() è ok, ma avete perso ignorare hashCode() metodo, solo di override il metodo hashCode(), funzionerà e non dimenticarti che devi sempre eseguire l'override di entrambi equals() and hashCode() o nessuno di essi per ottenere il comportamento corretto.Se stai pianificando di utilizzare gli oggetti come chiave nel meccanismo di hashing di quanto tu debba ignorare entrambi

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((first == null) ? 0 : first.hashCode()); 
    result = prime * result + ((last == null) ? 0 : last.hashCode()); 
    return result; 
} 
1

È necessario eseguire l'override di hashCode() in ogni classe che sostituisce equals(). In caso contrario, si verificherà una violazione del contratto generale per Object.hashCode(), che impedirà il corretto funzionamento della classe in combinazione con tutte le raccolte basate su hash, tra cui HashMap, HashSet, and Hashtable.

da Effective Java, da Joshua Bloch

+0

indica quattro spazi per ogni riga di codice – jsroyal

2

Qualsiasi Hash basato implementazione struttura dati (raccolta) in Java controlli duplicazione basa su due cose:

1: se equals metodo restituisce true per qualsiasi elementi che sono già memorizzati nella raccolta.

2: se il metodo restituisce il hashCodesame integer value per qualsiasi di elementi che sono già memorizzati nella collezione.

Quindi nel tuo caso non è stato sovrascritto il metodo hashCode, vuol dire che cercherà di verificare l'uguaglianza hashCode utilizzando implementazione predefinita metodo hashCode di Object classe che non è a conoscenza delle vostre last e first variabili.

Spero che aiuti.

0

Puoi anche vedere come verrà eseguito il tuo codice.

  1. Quando si tenta di aggiungere un elemento nel set chiama il codice hash e diventa bucket.

  2. Una volta ottenuto il valore hash dal codice hash, verrà eseguito l'uguaglianza degli override per tutti coloro che hanno lo stesso token hash.

Spero che questo aiuti.