Reputation: 6525
I don't understand why HashSet returns false for next example. Code:
import java.util.*;
public class Name {
private String first, last;
public Name(String first, String last){
this.first = first;
this.last = last;
}
public boolean equals(Name n){
return n.first.equals(first) && n.last.equals(last);
}
public int hashCode(){
return 31*first.hashCode()+last.hashCode();
}
public static void main(String[] args){
Set<Name> s = new HashSet<Name>();
Name n1 = new Name("Donald", "Duck");
Name n2 = new Name("Donald", "Duck");
s.add(n1);
System.out.print("HashCodes equal: ");
System.out.println( n1.hashCode() == n2.hashCode());
System.out.print("Objects equal: ");
System.out.println( n1.equals(n2) );
System.out.print("HashSet contains n1: ");
System.out.println(s.contains(n1));
System.out.print("HashSet contains n2: ");
System.out.println(s.contains(n2));
}
}
Result:
HashCodes equal: true
Objects equal: true
HashSet contains n1: true
HashSet contains n2: false
Excerpt from HashSet contains method description:
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
Question: why does it return false for both objects even though they are both not null and they are both equal in terms of hesh and value?
Upvotes: 1
Views: 206
Reputation: 1183
You have an error with overriding Object's equals method.
public boolean equals(Name n){
is just a method. The correct contract is:
public boolean equals(Object o){
// .....
}
Upvotes: 3
Reputation: 93892
Because you did'nt override the equals
method herited from the Object
class.
@Override
public boolean equals(Object o){
Name n = (Name)o;
return n.first.equals(first) && n.last.equals(last);
}
Output (demo here):
HashCodes equal: true
Objects equal: true
HashSet contains n1: true
HashSet contains n2: true
Upvotes: 8