2

When I create a hashset for my elements, for some reason I can add duplicate elements to it. I did override the equals and hashcode methods. Underneath is a bit of my code and an example of my problem. For simplicity I named my elements "element".

set.add(new element(new Point2D.Double(0,1), new Point2D.Double(2, 3), true));
set.add(new element(new Point2D.Double(0,1), new Point2D.Double(2, 3), true));
for (element e : set)
    System.out.println("set element : " + e.firstPoint2D.toString() 
                                    + e.secondPoint2D.toString() 
                                    + e.lastBoolean 
                                    + " and hashcode = " + e.hashCode());

this returns :

set element : Point2D.Double[0.0, 1.0] Point2D.Double[2.0, 3.0] true 
and hashcode = 3211
set element : Point2D.Double[0.0, 1.0] Point2D.Double[2.0, 3.0] true 
and hashcode = 3211

We clearly see they have the same hashcode, so why are they both in the hashset? I thought a hashset's utility was in the fact that it couldn't contain duplicates? Am I missing something? Here is equals and hashcode :

public boolean equals(element e) {
    if (this.firstPoint2D.equals(e.firstPoint2D) && 
     this.secondPoint2D.equals(e.secondPoint2D) && 
     this.lastBoolean == e.lastBoolean)
        return true;
    else
        return false;
}

@Override
public int hashCode() {
    int result = (int)(firstPoint2D.getX() + 10*firstPoint2D.getY() 
     + 100*secondPoint2D.getX() + 1000*secondPoint2D.getY());
    if (lastBoolean)
        return result + 1;
    else
        return result;
}
J. Schmidt
  • 419
  • 1
  • 6
  • 17
  • 1
    Could you post the `equals` method for `Point2D.Double`? You problem is likely there - in `Point2D.hashCode` you manually generate the `hashCode` for `Point2D.Double`, but in the `Point2D.equals` you rely on `Point2D.Double.equals` - this is likely wrong. – Boris the Spider Apr 01 '17 at 09:23
  • 2
    Try adding `@Override` to your equals method. Always. – Pshemo Apr 01 '17 at 09:25
  • @BoristheSpider I suspect OP is using `java.awt.geom.Point2D.Double`. – Pshemo Apr 01 '17 at 09:25
  • @Pshemo just saw your comment, that's certainly the problem. I didn't even notice... Oops. Either way, mixing external and internal `equals` and `hashCode` is odd. – Boris the Spider Apr 01 '17 at 09:26

1 Answers1

1

Your equals method is not correctly overridden and hence, it uses equals() method of Object class rather than the overridden version. equals() method ob Object class accepts an Object argument whereas the one you have overridden accepts element, following should work:

@Override
public boolean equals(Object e) {
    if ( e instanceof element &&
    this.firstPoint2D.equals(((element)e).firstPoint2D) && 
     this.secondPoint2D.equals(((element)e).secondPoint2D) && 
     this.lastBoolean == ((element)e).lastBoolean)
        return true;
    else
        return false;
}

Here's javadoc for equals().

logi-kal
  • 7,107
  • 6
  • 31
  • 43
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102