【问题标题】:HashSet retainAll using interfaceHashSet retainAll 使用接口
【发布时间】:2023-03-16 23:19:02
【问题描述】:

我有一些代码尝试使用HashSet.retainAll() 函数。

在下面的示例代码中,HashSet 包含接口IPerson,但对象Person 中的equals 函数从未到达。我什至尝试在界面和其他一些东西中公开 equals 函数。我觉得我已经尝试了一切。如何让retainAll() 使用我实现的 equal 函数?

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

【问题讨论】:

  • super.equals(Object obj); 在做什么? private name; 是另一个...请至少注意发布可编译代码。

标签: java collections equals


【解决方案1】:

您需要考虑name 以检查equality 并将其包含在计算hashCode 中,同时确保您关注hashcode and equals contract

【讨论】:

  • 正如提示:您可以使用 Eclipse -> Source -> Generate hashcode() 和 equals() 轻松创建这两种方法
【解决方案2】:

您需要覆盖hashCode,因为哈希集首先使用哈希码找到正确的“桶”,并且只有在找到其中的内容后才调用equals。这就是为什么永远不会调用您的 equals 方法的原因。 (如果你不重写 hashcode 方法,它会给每个新对象一个不同的 hashcode,所以即使你用相同的名字调用 new Person("name") 两次,它们也不会有相同的 hashcode)

【讨论】:

  • 是的,问题确实是 hashCode ,它另外(显然)必须考虑区分大小写。即return getName().toLowerCase().hashCode();
猜你喜欢
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多