我想有一个SortedSet的集(设置自己,在这种情况下,但不一定在一般的),这种通过收集的大小。这似乎违反了禁止以具有比较一致与平等()-即两个集合,也可以不等(由具有不同的元素),但比较的同样的价值(因为他们有同样数量的元素)。

名义上,我也可以把进入比较的方式进行排序设置平等的尺寸,但是使用这种不会利用这一点,并没有真的一个有用的+直观的方式比较集的大小相等的(至少在我的特定情况),因此这似乎是一种浪费。

这种情况下不一致似乎是一个问题吗?

有帮助吗?

解决方案

作为ChssPly76在评论中写道,你可以使用的hashCode决定在两个集合有相同的大小,但不相等的情况下的compareTo电话。这工作得很好,但在你有两个集合相同大小的罕见情况下,是不相等的,但有相同的hashCode。诚然,发生这种情况的几率非常小,但它是可以想象的。如果你想成为非常小心,而不是hashCode时,使用System.identityHashCode代替。这应该给你一个唯一的编号为每个集合,你不应该得到的碰撞。

在这一天结束,这让你有两个类别与配合尺寸的情况下,集合中按大小排序设置,任意排序的功能。如果这是你所需要的,这不是远远低于普通的比较会。如果需要排序是不同的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;
}

其他提示

SortedSet 接口扩展的核心 Set 因此应该符合合同中概述 Set 规范。

唯一可能的方式来实现,这是你的元素 equal() 法行为须符合你的 Comparator -其中的原因是,核心 Set 工作的基础上平等而 SortedSet 工作的基础上进行比较。

例如, add() 方法中定义的一套核心指定的接口,你不能添加一个元件的设定如果已经有一个元素的 equal() 方法就会回真的有这个新的元素作为论据。好了, SortedSet 不使用 equal(), 它使用 compareTo().所以如果你的 compareTo() 返回 false 你的元素将能加入,甚至如果 equals() 返回 true, ,从而打破了 Set 合同。

所有这些都不是 实际 问题本身,但是。 SortedSet 行为始终是一致的,即使 compare() vs equals() 不是。

  

这似乎违背了禁制   有比较一致   与equals() - 即,两个集合   可以是不相等的(由具有不同   元素),但比较相同   值(因为它们具有相同的   元素的数量)。

没有要求,无论是表示(在Javadoc)或暗示,即一个Comparator是具有对象的实现boolean equals(Object)一致。

请注意ComparableComparator不同的接口使用不同的目的。 Comparable用于定义一类“自然”顺序。在这种情况下,这将是equals一个坏主意,并compateTo不一致。相反,当要使用不同的顺序的一类的自然顺序一个Comparator被使用。

编辑:下面是从的Javadoc的SortedSet完整的段落

  

请注意,通过一个保持的顺序   有序集合(无论是否明确   比较器提供的)必须   与equals一致,如果排序   一套是要正确地实现Set   接口。 (见可比   接口或比较器接口,用于   的一致的精确定义   与equals)。这是因为在   Set接口是来定义   equals操作,但有序   组执行所有元件比较   使用其的compareTo(或比较)   方法,所以两个元件是   认为等于通过该方法是,从   有序集合的角度来看,   等于。 有序集合的行为是   定义良好的,即使它的排序   与equals不一致;这只是   不服从的总承包合同   Set接口。

我强调最后一句。问题的关键是,这样的SortedSet的将工作,你很可能会想到,但某些操作的行为将不Set规格完全一致......因为规范定义的equals方法方面的行为。

所以,事实上,有的一致性(我的错)所陈述的要求,但忽略它的后果并不像你想象的那样糟糕。当然,它是由决定是否应该这样做。据我估计,应该OK,只要你彻底注释代码,并确保该SortedSet的不“泄漏”。

不过,我也不清楚,对于收藏比较器,只有着眼于一个集合“大小”是去工作......从语义的角度。我的意思是,你真的想说,与(比如说)2种元素的所有集合都是平等的?这将意味着您所设定的永远只能包含任何给定大小的一个集合......

有没有理由为什么Comparator应该返回相同的结果equals()。事实上,引入了Comparator API,因为equals()是不够的:如果要排序的集合,你必须知道两个元素是否有或大或小

这是一点点奇怪的SortedSet作为标准API的一部分打破在Set接口中定义的合同,并使用比较器来定义平等代替equals方法,但是这是它是如何。

如果您的实际问题是,根据containted收藏大小排序集合的集合,你是用List,更好的,你可以使用Collections.sort(名单,比较>)进行排序;

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top