HashSet retainAll使用接口

时间:2014-06-23 19:48:11

标签: java collections equals

我有一些代码,我尝试使用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

2 个答案:

答案 0 :(得分:4)

您需要考虑name检查equal并将其包含在计算hashCode中,同时确保您遵循hashcode and equals contract

答案 1 :(得分:1)

您需要覆盖hashCode,因为哈希集使用哈希码来查找正确的“#”桶。首先,只有在它找到内容后才调用等号。这就是为什么你的equals方法永远不会被调用的原因。 (如果你不覆盖哈希码方法,它会为每个新对象提供不同的哈希码,所以即使你用同一个名称调用new Person("name")两次,他们也不会拥有相同的哈希码)