哈希集包含重复的条目

2022-09-03 00:08:26

当 equals 方法表示值相同时,HashSet 仅存储值 1。我就是这么想的。

但是现在我正在将元素添加到哈希集,其中等于s方法返回真,并且集合的大小仍在增长??对不起,我很困惑。一些我错的提示会很好。

Element t1 = new Element(false, false, false, false);
Element t2 = new Element(true, true, true, true);
Element t3 = new Element(false, false, false, false);

if (t1.equals(t3))
    System.out.println("they're equal");

Set<Element> set = new HashSet<>();

set.add(t1);
set.add(t2);
set.add(t3);

System.out.println("set size: " + set.size());

所以在这个例子中,我的控制台输出是:

它们等于
设置大小:3

这对我来说毫无意义。大小应该为 2 吗?


答案 1

问题是您的类没有重写 and 方法,或者这些实现已损坏。ElementequalshashCode

From Object#equals method javadoc:

equals 方法在非空对象引用上实现等价关系:

  • 它是自反的:对于任何非空引用值 x,x.equals(x) 应返回 true。
  • 它是对称的:对于任何非空引用值 x 和 y,x.equals(y) 应返回 true 当且仅当 y.equals(x) 返回 true。
  • 它是可传递的:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true 而 y.equals(z) 返回 true,则 x.equals(z) 应返回 true。它是一致的:对于任何非空引用值 x 和 y,-x.equals(y) 的多次调用始终返回 true 或一致返回 false,前提是不修改对象的相等比较中使用的任何信息。
  • 对于任何非空引用值 x,x.equals(null) 应返回 false。

From Object#hashCode method javadoc:

哈希码的总合约是:

  • 每当在执行 Java 应用程序期间在同一对象上多次调用它时,hashCode 方法必须一致地返回相同的整数,前提是不修改对象的相等比较中使用的任何信息。此整数不必从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果根据 equals(Object) 方法,两个对象相等,则对两个对象中的每个对象调用 hashCode 方法必须生成相同的整数结果。
  • 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要在两个对象的每个对象上调用 hashCode 方法必须生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

确保这些方法的实现满足这些规则,并且您的(由 a 支持)将按预期工作。SetHashSet


答案 2

您的对象具有不同的哈希值,因此 HashSet 会“放置”,然后放在不同的“存储桶”中。