2013-05-09 16 views
13

Wenn ich den folgenden Code ausführe, dann ist die Ausgabe 2, was bedeutet, dass das Set 2 Elemente enthält. Ich denke jedoch, dass dieser Satz 1 enthalten sollte, da beide Objekte basierend auf Hashcode() Wert sowie .equals() Methode sind. Scheint wie ein offensichtlicher Fehler in meinem Verständnis?Java: Doppelte Objekte werden zum Set hinzugefügt?

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; 
    } 
} 

Antwort

22

Ihre Hash c ode Methode der Objektklasse nicht Hash C ode Methode nicht außer Kraft setzen und somit Vertrag Ihre Methode equals bricht, da sie nicht mit den hashCode Ergebnissen nicht einverstanden ist, und Sie können Objekte, die sind "gleich" aber haben unterschiedliche hashCodes.

Hinweis: Sie sollten immer die @Override Annotation beim Überschreiben von Methoden verwenden, da dies Ihnen hilft, diese und ähnliche Fehler zu finden.

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

Auch werden Sie Ihre Code-Formatierung zu verbessern, vor allem, wenn der Code hier für unseren Bericht veröffentlichen. Wir werden Ihren Code besser verstehen und Ihnen helfen können, wenn er den Standards entspricht (deshalb existieren Standards). Versuchen Sie also, Ihre Einrückungen konsistent mit allen Codezeilen zu halten, die sich im gleichen Block auf derselben Ebene befinden, und Sie sollten sicher sein, dass der Basiscode, einschließlich der Importe, der äußeren Klassendeklarationen und der geschweiften Klammern, linksbündig ist :

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; 
    } 
} 

Für eine schöne Rezension hierzu lesen Sie bitte:. Overriding equals and hashCode in Java

+0

Danke! Ich würde nie vergessen, @Override mehr zu benutzen :) –

+0

@snow_leopard: Es ist eine gute Angewohnheit, hineinzukommen. Viel Glück! –

+0

Neben "@Override" musste ich auch eine Zeile in der Equals-Funktion hinzufügen, sonst konnte die Menge keine Duplikate erkennen und enthielt immer ein Objekt mit demselben Inhalt mehrfach: if (this.hashCode() == msg. hashCode()) return true; –

3

die @Overrides Annotation die Methode mit dem gleichen Namen in der Superklasse“

@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

außer Kraft zu setzen ist Ihr Methode ha shcode sollte hashCode (Großbuchstabe "C") genannt werden.

Wenn Sie Methoden überschreiben möchten, sollten Sie die @Override Annotation verwenden.

Wenn Sie diese Anmerkung verwendet hätten, hätten Sie das Problem früher bemerkt, da der Code nicht kompiliert worden wäre.

Verwandte Themen