2016-04-23 11 views
9

Ich habe die folgende Klasse:HashSet fügt doppelte Einträge trotz sowohl hashCode Umsetzung() und equals()

class Point 
{ 
    double x, y; 

    // .... constructor and other functions here 

    public boolean equals(Point p) 
    { 
     if(p==null) return(false); 
     return(x==p.x && y==p.y); 
    } 

    public int hashCode() 
    { 
     int result=17; 

     long c1=Double.doubleToLongBits(x); 
     long c2=Double.doubleToLongBits(y); 

     int ci1=(int)(c1^(c1 >>> 32)); 
     int ci2=(int)(c2^(c2 >>> 32)); 

     result = 31 * result + ci1; 
     result = 31 * result + ci2; 

     return result; 
    } 
} 

Nun, wenn ich schreibe den folgenden Code:

Point x=new Point(11,7); 
    Point y=new Point(11,7); 

    System.out.println("hash-code of x=" + x.hashCode()); 
    System.out.println("hash-code of y=" + y.hashCode()); 
    System.out.println("x.equals(y) = " + x.equals(y)); 
    System.out.println("x==y = " + (x==y)); 

    java.util.HashSet<Point> s=new java.util.HashSet<Point>(); 
    s.add(x); 
    System.out.println("Contains "+y.toString()+" = "+s.contains(y)); 
    s.add(y); 
    System.out.println("Set size: "+s.size()); 
    java.util.Iterator<Point> itr=s.iterator(); 
    while(itr.hasNext()) System.out.println(itr.next().toString()); 

Ich erhalte die folgende Ausgabe:

hash-code of x=79052753 
hash-code of y=79052753 
x.equals(y) = true 
x==y = false 
Contains (11.0,7.0) = false 
Set size: 2 
(11.0,7.0) 
(11.0,7.0) 

Bitte helfen Sie mir zu verstehen, warum enthält() gibt false (auch nach equals() und hashCode() den gleichen Wert zurückgeben) und wie kann ich dies korrigieren (d. h. Verhindern, dass Java doppelte Elemente hinzufügt). Danke im Voraus.

+2

Wow! Es wäre so toll, wenn alle Fragen so klar und verständlich sind, und Code und Ausgaben für die Wiedergabe haben. Gut gemacht! – Seelenvirtuose

Antwort

7

Sie überschreiben die equals-Methode in Object nicht.

Die Unterschrift des Gleichheits Methode ist:

public boolean equals(Object obj) 

und nicht

public boolean equals(Point obj) 

Und bitte vergleichen Sie nicht doppelte Werte mit ==. Sie sollten stattdessen Double.equals verwenden.

+1

Der Wert einfacher Typen kann mit == –

+2

@SergeyMorozov - Nein verglichen werden. Die Verwendung von == für Gleitkommavergleiche wird nicht empfohlen. Es ist nicht sicher. – Madhusudhan

+0

Danke, es hat mein Problem gelöst. Was den Vergleich anbelangt, gibt Double.equals gemäß der Dokumentation false zurück, wenn -0.0 und +0.0 verglichen werden; Ich denke, ich würde bei == bleiben als Double.equals(). – user1637645

6

Sie haben die Methodensignatur von Object.equals(Object) geändert, sodass Sie equals nicht korrekt überschreiben. Ich schlage vor, dass Sie die @Override Annotation verwenden, um diese Klasse von Fehlern zu erfassen. Ihre Methode sollte etwa so aussehen:

@Override 
public boolean equals(Object o) 
{ 
    if (this == o) { 
     return true; 
    } 
    if (o instanceof Point) { 
     Point p = (Point) o; 
     return(x==p.x && y==p.y); 
    } 
    return false; 
} 
+0

Ich habe meinen Code geändert und diesmal richtig übergangen und es hat mein Problem gelöst. Danke vielmals. – user1637645

Verwandte Themen