I have the following class:
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;
}
}
Now, if I write the following 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());
I am getting the following output:
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)
Please help me in understanding why contains() returns false (even after equals() and hashCode() return the same value) and how can I rectify this (i.e. preventing Java from adding duplicate elements). Thanks in advance.
Duplicates: HashSet doesn't allow duplicate values. HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.
The problem is that your Element class has not overridden the equals and hashCode methods or these implementations are broken. It is reflexive: for any non-null reference value x, x. equals(x) should return true.
For a hashed collection you need to implement equals()/hashCode() appropriately for Employee, and then a HashSet will guarantee you don't have any duplicates... Also: you don't need to check if the set contains the element first. Just call add , and if the element already exists in the set, it won't be added again.
You have changed the method signature from Object.equals(Object)
, so you aren't correctly overriding equals
. I suggest you use the @Override
annotation to catch this class of bugs. Your method should look something like,
@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;
}
You are not overriding the equals method in Object.
The signature of equals method is:
public boolean equals(Object obj)
and not
public boolean equals(Point obj)
And please do not compare double values using ==. You should use Double.equals instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With