2013-05-09 17 views
13

Se eseguo il codice seguente, l'uscita è 2, il che significa che il set contiene 2 elementi. Tuttavia, ritengo che il set debba contenere 1 poiché entrambi gli oggetti sono uguali in base al valore hashcode() e al metodo .equals(). Sembra un errore evidente nella mia comprensione?Java: oggetti duplicati vengono aggiunti al set?

package HELLO; 

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

public class Test { 

    public static void main(String[] args) throws Exception { 
     Set<Alpha> s = new HashSet<Alpha>(); 
     Alpha a1 = new Alpha(); 
     Alpha a2 = new Alpha(); 
     s.add(a1); 
     s.add(a2); 
     System.out.println(s.size()); 
    } 
} 

class Alpha { 
    int a = 10; 

    public int hashcode() { 
     return a; 
    } 

    public boolean equals(Object obj) { 
     return (obj instanceof Alpha && ((Alpha) obj).a == this.a); 
    } 

    public String toString() { 
     return "Alpha : " + a; 
    } 
} 

risposta

22

tuo hash c metodo ode non prevale hash C metodo ode della classe Object e quindi il contratto metodo equals pause dal momento che non sono d'accordo con i risultati hashCode, e si può avere oggetti che sono "uguali" ma hanno hash differenti.

Ricordare: si deve sempre utilizzare l'annotazione @Override quando si esegue l'override dei metodi poiché ciò consentirà di rilevare errori simili e simili.

@Override // ** don't forget this annotation 
public int hashCode() { // *** note capitalization of the "C" 
    return a; 
} 

Inoltre, si vuole migliorare la formattazione del codice, in particolare quando si postano il codice qui per la nostra recensione. Saremo in grado di capire meglio il tuo codice e aiutarti se è conforme agli standard (ecco perché esistono gli standard). Quindi cerca di mantenere le tue rientranze coerenti con tutte le code line che si trovano nello stesso blocco rientrate allo stesso livello, e vorresti essere sicuro che il codice di livello base, incluse le importazioni, le dichiarazioni di classe esterne e la parentesi graffa di estremità, sia a sinistra :

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

public class Test { 

    public static void main(String[] args) throws Exception { 
     Set<Alpha> s = new HashSet<Alpha>(); 
     Alpha a1 = new Alpha(); 
     Alpha a2 = new Alpha(); 
     s.add(a1); 
     s.add(a2); 
     System.out.println(s.size()); 
    } 
} 

class Alpha { 
    int a = 10; 

    @Override 
    public int hashCode() { 
     return a; 
    } 

    public String toString() { 
     return "Alpha : " + a; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
     return true; 
     if (obj == null) 
     return false; 
     if (getClass() != obj.getClass()) 
     return false; 
     Alpha other = (Alpha) obj; 
     if (a != other.a) 
     return false; 
     return true; 
    } 
} 

per una bella recensione su questo, si prega di leggere:. Overriding equals and hashCode in Java

+0

Grazie! Non dimenticherò mai più di usare @Override :) –

+0

@snow_leopard: è una grande abitudine entrare. In bocca al lupo! –

+0

Oltre a "@Override" dovevo aggiungere anche una riga nella funzione equals, altrimenti l'insieme non era in grado di rilevare duplicati e conteneva sempre un oggetto con lo stesso contenuto più volte: if (this.hashCode() == msg. hashCode()) return true; –

3

I @Overrides annotazione è l'override del metodo con lo stesso nome nella classe super"

@Override 
public int hashCode() { 
    return a; 
} 

@Override 
public boolean equals(Object obj) { 
    return (obj instanceof Alpha && ((Alpha) obj).a == this.a); 

} 

@Override 
public String toString() { 
    return "Alpha : " + a; 
} 
4

tua metodo ha shcode deve essere denominato hashCode (lettera maiuscola "C").

Se si pianifica di eseguire l'override dei metodi, è necessario utilizzare l'annotazione @Override.

Se avessi usato quell'annotazione, avresti notato il problema prima, poiché il codice non sarebbe stato compilato.

Problemi correlati