Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么可比自然排序需要与equals方法一致?_Java_Generics_Collections - Fatal编程技术网

Java 为什么可比自然排序需要与equals方法一致?

Java 为什么可比自然排序需要与equals方法一致?,java,generics,collections,Java,Generics,Collections,度假回来:)带着问题。我正在阅读类似的接口文档 . 我理解,我们使用comparable,因为它将为我们提供排序和自然排序。在文档中,它写为 强烈建议(尽管不是必需的)自然 排列顺序必须与等号一致。这是因为排序集 没有显式比较器的(和排序贴图)在 它们与自然顺序为的元素(或键)一起使用 与平等不一致。特别是这样一个排序集(或排序集) map)违反了已定义的set(或map)总合同 根据equals方法 “可比”与“相等”之间的关系。Comparable有compareTo方法,为什么它需要与eq

度假回来:)带着问题。我正在阅读类似的接口文档 . 我理解,我们使用comparable,因为它将为我们提供排序和自然排序。在文档中,它写为

强烈建议(尽管不是必需的)自然 排列顺序必须与等号一致。这是因为排序集 没有显式比较器的(和排序贴图)在 它们与自然顺序为的元素(或键)一起使用 与平等不一致。特别是这样一个排序集(或排序集) map)违反了已定义的set(或map)总合同 根据equals方法

“可比”与“相等”之间的关系。Comparable有compareTo方法,为什么它需要与equals方法一致?我无法理解这个概念

也引用消息来源,有人能详细说明这一点吗

例如,如果添加两个键a和b,则(!a.equals(b)&& a、 将(b)==0)与不使用显式 比较器,第二个加法操作返回false(和 排序集不会增加),因为a和b从 排序集的透视图


谢谢。

简短回答:无论何时
比较(a,b)
对于两个对象
a
b
a.equals(b)
b.equals(a)
返回
0
,反之亦然

详细回答:正如
Comparable
文档中所述,
Comparable
的实现强制执行总排序。其中一个问题是“反对称性”:如果我们定义一个总序≤, 然后:

如果≤ b和b≤ a然后a=b

这表示为
compareTo()
0
返回值


您引用的文本中提到的方法和类利用了这一特性,以实现更正确、更高效的行为

compareTo返回0的语义是这两个对象是相等的。在另一种方法中对同一关系进行另一种定义显然会导致许多问题,正如您的报价中所述:
SortedSet
实现中的典型算法依赖于
compareTo
,但是
集合
接口的一般约定规定它不能包含两个
等于
的对象。
compareTo
equals
的报告不一致将导致这种情况。

您可以在Set的文档中看到:

请注意,由集合维护的排序(无论是否为 提供了显式比较器)必须与equals一致 如果要正确实现{@code Set}接口。(见 {@code Comparable}或{@code Comparator}的精确定义 这是因为{@code Set} 接口是根据{@code equals}操作定义的,但 {@code TreeSet}实例使用其 {@code compare}(或{@code compare})方法,因此 从集合的角度来看,通过该方法被视为相等的, 相等。集合的行为是定义良好的,即使其 排序与相等不一致;它就是不遵守规则 {@code Set}接口的总合同


非常感谢。我现在明白这个概念了。这意味着Set接口使用equals方法促进相等比较?是的,因为精髓的
Set
实现不关心其元素的任何顺序:它只关心它们都是不同的。可以说,
equals
的主要作用是使
Set
s起作用。多谢了。我现在明白这个概念了。非常感谢。@benz:既然是Marko的回答帮助了你,你应该接受:)。你的第二句话是关于我在回答中已经解释过的,只是用了不同的方式,更正式的表达方式。我编辑这个问题是为了提出另一个造成混乱的观点。我完全理解你们所描述的概念。非常感谢你。你能看看我编辑过的问题并告诉我为什么第二次添加到sortedset中吗?@benz:像Marko一样,我不知道这里有什么不清楚的地方。您确实注意到它是
!a、 等于(b)
,而不是
a。等于(b)
?如果是这样,请进一步编辑您的问题,以说明您对该陈述的不理解之处。我正在剖析该陈述。该条件意味着,如果a和b不是相等的对象,并且它们的比较操作返回0,则添加到集合中。我感到困惑的是,为什么第二次添加操作不允许它们添加,并且大小也不会增加。这句话把我弄糊涂了。@benz:因为Java
Set
的工作原理与数学集合类似,它包含不同的对象。因此,如果您已经添加了一个对象
a
,然后尝试添加被认为“相同”(至少通过
equals()
)的对象
b
,那么操作将不会做任何事情,因为就集合而言,
b
已经在集合中,因为它是“相同的”作为
a
。我想知道让
TreeSet
支持“无序项”节点类型需要多少成本,比如说,将一个项添加到一个已经包含
compareTo
的项的树中会产生零,但
等于
返回
false
将创建一个“无序项”节点,并且遇到“无序项”节点的搜索将搜索这两个分支。这将允许这种类型的行为就像一个普通的
集合
,即使它只有在大多数项目可以通过等级区分的情况下才能有效地执行。