HashSet包含重复的条目

tOb*_*Obi 14 java unique set hashset

当equals方法表明它们是相同的时,HashSet只存储值1.那正是我所想.

但是现在我正在向HashSet添加Elements,其中equals方法返回true并且set的大小仍在增长?对不起,我很困惑.一些提示我错了会很好.

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());
Run Code Online (Sandbox Code Playgroud)

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

它们的
大小相等:3

这对我来说没有意义..大小应该是2吗?

Lui*_*oza 20

问题是你的Element类没有覆盖equalshashCode方法或这些实现被破坏.

Object#equals方法javadoc:

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

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

Object#hashCode方法javadoc:

hashCode的一般契约是:

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

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

  • @tobi除非你重写“hashCode()”和“equals()”,否则你就违反了这些方法的约定。仅仅因为 `HashSet#add()` 的 Javadoc 没有引用 `hashCode()` 并不意味着您可以忽略 `equals()` 和 `hashCode()` 契约。 (2认同)