这是我的代码:
public class testGui {
public static void main(String[] arg){
class TESTS{
String t;
public TESTS(String t){
this.t = t;
}
@Override
public boolean equals(Object x){
System.out.println("My method is called...");
if(x instanceof TESTS){
TESTS zzz = (TESTS) x;
return zzz.t.compareTo(t)==0;
}
else return false;
}
}
HashSet<TESTS> allItems = new HashSet<TESTS>();
allItems.add(new TESTS("a"));
allItems.add(new TESTS("a"));
System.out.println(allItems.contains(new TESTS("a")));
}
}
我不明白为什么hashset contains方法没有调用我们的规范中提到的equals方法:
更正式地说,添加指定的 如果此设置,则为此集合的元素o 不包含元素e (o == null?e == null:o.equals(e))
我的代码返回false而不是进入我的equals方法。
非常感谢您的回答!
答案 0 :(得分:13)
答案 1 :(得分:7)
HashSet取决于每个对象的HashCode。在调用equals方法之前,将调用hashCode方法。如果哈希码相等,则hashset认为值得评估equals方法。
实现一个哈希码方法,如果a.equals(b)== true,那么a.hashCode()== b.hashCode()
它应该像你期望的那样开始工作。
答案 2 :(得分:3)
您还应该实施hashCode
,以便与equals
保持一致。 HashSet
使用hashCode
方法决定将项目放入哪个存储区,并仅在两个项目的哈希码相同时调用equals
。
Effective Java,2nd Edition 在第9项:覆盖hashCode
}时始终覆盖equals
,讨论此规则(以及破解它的后果)强>
答案 3 :(得分:0)
由于大多数评论都是......只是覆盖哈希码方法(下面的示例),你应该很好。
@Override
public int hashCode() {
return t.hashCode()*31;
}