我想在SortedSet
|中创建一个可用的类SortedMap
。
class MyClass implements Comparable<MyClass>{
// the only thing relevant to comparisons:
private final String name;
//...
}
类'实例必须按名称属性排序 但是,我不希望同等命名的实例被认为是平等的。
所以SortedSet
内容看起来像 a,a,a,b,c 。
(通常情况下,SortedSet
只允许 a,b,c )
首先:这是(哲学上)一致吗?
如果是这样,我不得不期待不可预测的行为
覆盖equals(...)
和hashCode()
?
修改
对不起,我的问题似乎不一致:
我想在设置中添加多个“相等”值,这不允许这样做
按概念。
所以,请不要再回答我的问题了
感谢所有已回复的人。
答案 0 :(得分:18)
让我问你一个问题:让a.compareTo(b)
返回0并a.equals(b)
返回false
是否有意义?
我会改用Comparator<MyClass>
。这就是为什么我所知道的所有SortedMap
/ SortedSet
实现都允许您在创建时传入Comparator
。
答案 1 :(得分:4)
来自Javadoc for Comparable
强烈建议(尽管不是 要求)自然的排序 与平等一致。就是这样 因为有序集(和有序映射) 没有明确的比较器表现 “奇怪地”与它们一起使用时 元素(或键)的自然 排序与equals
不一致
如果你想使compareTo与equals()不一致,建议你通过提供一个实现Comparator的类来使用显式比较器。
如果是这样,当我不重写equals(...)和hashcode()时,我是否必须预料到不可预测的行为?
您仍应覆盖equals()和hashcode()。
答案 2 :(得分:2)
Effective Java建议如果您未实施与compareTo
一致的equals
,则应明确说明:
推荐的语言是“注意: 这个类有一个自然的顺序 与equals不一致。“
答案 3 :(得分:0)
只需将此代码放入equals方法中,再也不要再考虑它了:
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof MyClass)) return false;
return 0 == this.compareTo((MyClass) obj);
}