Java文档中使用的约定

Java文档中使用的约定,java,hashset,treeset,Java,Hashset,Treeset,为什么针对TreeSet和HashSet的add()方法的Oracle Java API文档说明: 仅当(e==null?e2==null:e.equals(e2)) 但是,TreeSet使用compareTo(),而HashSet使用hashCode()确定相等性。两者都忽略equals()的值。我担心文档不准确,或者是我对约定或算法的理解有缺陷?您认为TreeSet文档不正确是正确的 关于HashSet,您是不正确的,因为它确实使用了equals()hashCode()不用于相等性测试,仅用

为什么针对
TreeSet
HashSet
add()
方法的Oracle Java API文档说明:

仅当
(e==null?e2==null:e.equals(e2))


但是,
TreeSet
使用
compareTo()
,而
HashSet
使用
hashCode()
确定相等性。两者都忽略
equals()
的值。我担心文档不准确,或者是我对约定或算法的理解有缺陷?

您认为TreeSet文档不正确是正确的


关于HashSet,您是不正确的,因为它确实使用了
equals()
hashCode()
不用于相等性测试,仅用于快速搜索。

TreeSet
在其文档中解释了这一点:


请注意,如果要正确实现set接口,set维护的顺序(无论是否提供显式比较器)必须与equals一致。(请参阅Comparable或Comparator以获得与equals一致的精确定义。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此此方法认为相等的两个元素是,从集合的角度来看,相等。即使集合的顺序与equals不一致,集合的行为也是定义良好的;它只是没有遵守Set接口的总合同


对于
HashSet
,文档隐含的期望是
Set
中的对象得到正确实现;如果
hashCode()
没有正确实现,那么它就不是
HashSet
违反了它的规范,而是传递给它的对象。

“一个集合的行为是定义良好的,即使它的顺序与equals不一致。”然而,该行为与文档中的定义不一致,这就是我想知道的。为什么文档对此不具体(准确)?最好说:e==null?e2==null:e.compareTo(e2)==0)如果hashCode()设置为始终返回相同的代码,则add()的行为似乎依赖于equals()。但是如果我创建一个对象,其中equals()总是返回'true',并且不重写hashCode()-因此它对于不同的对象是不同的-那么add()将添加多个对象。因此,add()的行为似乎比文档中所述的更复杂。正如Louis所说,这些情况不在合同范围内,但我对实现感兴趣(因为它没有做它所说的事情)-有人知道是否有规范吗?@user3038094-我建议阅读HashMap的工作原理。然后您将了解为什么不总是调用
equals()
方法。无论如何,在一般意义上,HashSet确实使用
equals()
进行相等性测试。谢谢jtahlborn-我已经听从了你的建议,明白了你的意思。如果hashCode()不同,那么算法不需要计算equals(),它只在hashCode()相同时使用equals()。这大概是因为假定hashCode()的计算速度比equals()快,还是因为hashCode()必须进行计算?所以最好在文档中说:e==null?e2==null:e.hashCode()==e2.hashCode()?e、 hashCode()==e2.hashCode():e.equals(e2)==0抱歉-编辑时间用完:e==null?e2==null:e.hashCode()==e2.hashCode()?正确:e等于(e2)