Java SortedSet+;比较器,与equals()问题的一致性
我希望有一个集合的SortedSet(在本例中,集合本身,但不一定是一般集合),它按集合大小进行排序。这似乎违反了将比较器与equals()保持一致的规定-即,两个集合可能不相等(通过具有不同的元素),但与相同的值进行比较(因为它们具有相同的元素数) 理论上,我也可以使用Comparator方法对大小相等的集合进行排序,但使用排序方法不会利用这一点,而且没有一种真正有用的+直观的方法来比较大小相等的集合(至少在我的特定情况下),因此这似乎是一种浪费Java SortedSet+;比较器,与equals()问题的一致性,java,equals,comparator,sortedset,Java,Equals,Comparator,Sortedset,我希望有一个集合的SortedSet(在本例中,集合本身,但不一定是一般集合),它按集合大小进行排序。这似乎违反了将比较器与equals()保持一致的规定-即,两个集合可能不相等(通过具有不同的元素),但与相同的值进行比较(因为它们具有相同的元素数) 理论上,我也可以使用Comparator方法对大小相等的集合进行排序,但使用排序方法不会利用这一点,而且没有一种真正有用的+直观的方法来比较大小相等的集合(至少在我的特定情况下),因此这似乎是一种浪费 这种不一致的情况似乎是个问题吗?没有理由让比较
这种不一致的情况似乎是个问题吗?没有理由让比较器返回与
equals()相同的结果。事实上,引入比较器API是因为equals()
还不够:如果要对集合进行排序,必须知道两个元素是较小还是较大。比较器没有理由返回与equals()
相同的结果。事实上,之所以引入比较器API,是因为equals()
还不够:如果要对集合进行排序,必须知道两个元素的大小。接口扩展了核心,因此应该符合集合规范中概述的契约
实现这一点的唯一可能方法是使元素的equal()
例如,在核心集接口中定义的方法指定,如果已经有一个元素的equal()
方法将以该新元素作为参数返回true,则不能将元素添加到集合中。好的,SortedSet
不使用equal()
,它使用compareTo()
。因此,如果您的compareTo()
返回false
,那么即使equals()
返回true
,您的元素也将被添加,从而打破了集合
契约
然而,这一切本身都不是一个实际的问题<代码>分类数据集
行为始终一致,即使比较()
与相等()
不一致。接口扩展了核心,因此应符合集
规范中概述的合同
实现这一点的唯一可能方法是使元素的equal()
例如,在核心集接口中定义的方法指定,如果已经有一个元素的equal()
方法将以该新元素作为参数返回true,则不能将元素添加到集合中。好的,SortedSet
不使用equal()
,它使用compareTo()
。因此,如果您的compareTo()
返回false
,那么即使equals()
返回true
,您的元素也将被添加,从而打破了集合
契约
然而,这一切本身都不是一个实际的问题SortedSet
行为总是一致的,即使compare()
与equals()
不一致。SortedSet作为标准API的一部分,打破了Set接口中定义的契约,使用比较器定义相等,而不是equals方法,这有点奇怪,但事实就是这样
如果您的实际问题是根据包含的集合的大小对集合进行排序,那么最好使用列表,可以使用集合进行排序 有点奇怪,SortedSet作为标准API的一部分打破了Set接口中定义的契约,使用比较器来定义相等,而不是equals方法,但事实就是这样
如果您的实际问题是根据包含的集合的大小对集合进行排序,那么最好使用列表,可以使用集合进行排序 正如ChssPly76在评论中所写,如果两个集合大小相同但不相等,则可以使用hashCode来决定compareTo调用。这很好,除非在罕见的情况下,您有两个大小相同的集合,它们不相等,但具有相同的哈希代码。诚然,发生这种情况的可能性很小,但这是可以想象的。如果您想非常小心,请使用System.identityHashCode代替hashCode。这将为每个集合提供一个唯一的编号,并且不会发生冲突
在一天结束时,这为您提供了按大小排序集合中集合的功能,对于大小匹配的两个集合,可以任意排序。如果这就是你所需要的,它不会比通常的比较慢很多。如果您需要不同JVM实例之间的顺序保持一致,那么这将不起作用,您必须以其他方式来完成
伪代码:
if (a.equals(b)) {
return 0;
} else if (a.size() > b.size()) {
return 1;
} else if (b.size() > a.size()) {
return -1;
} else {
return System.identityHashCode(a) > System.identityHashCode(b) ? 1 : -1;
}
正如ChssPly76在注释中所写的,在两个集合大小相同但不相等的情况下,可以使用hashCode来决定compareTo调用。这很好,除非在罕见的情况下,您有两个大小相同的集合,它们不相等,但具有相同的哈希代码。诚然,发生这种情况的可能性很小,但这是可以想象的。如果您想非常小心,请使用System.identityHashCode而不是hashCode