我有一些代码,我尝试使用HashSet.retainAll()
函数。
在下面的示例代码中,HashSet
包含接口IPerson
,但永远不会到达对象Person
中的等于函数。我甚至试图在界面中公开equals函数和其他一些东西。我觉得我已经尝试了一切。如何让retainAll()
使用我实现的同等功能?
class Person implements IPerson {
private String name;
public Person(String name){
this.name = name;
}
@Override
public boolean equals(Object obj){
System.out.println("calling equals");
return super.equals(Object obj);
}
}
HashSet<IPerson> persons1 = new HashSet<IPerson>();
persons1.add(new Person("Jane"));
persons1.add(new Person("Joel"));
persons1.add(new Person("Joe"));
HashSet<IPerson> persons2 = new HashSet<IPerson>();
persons2.add(new Person("Jane"));
persons2.add(new Person("Joel"));
persons1.retainAll(persons2);
// expect sysout from Person.equals()
System.out.println(persons1.size());
// prints 0
答案 0 :(得分:4)
您需要考虑name
检查equal
并将其包含在计算hashCode
中,同时确保您遵循hashcode
and equals
contract
答案 1 :(得分:1)
您需要覆盖hashCode
,因为哈希集使用哈希码来查找正确的“#”桶。首先,只有在它找到内容后才调用等号。这就是为什么你的equals方法永远不会被调用的原因。 (如果你不覆盖哈希码方法,它会为每个新对象提供不同的哈希码,所以即使你用同一个名称调用new Person("name")
两次,他们也不会拥有相同的哈希码)