在Java中,我应该何时实施Comparable<Something>
而不是实施equals
方法?我理解每次实施equals
时我都必须实施hash code
。
修改
根据我得到的答案:
如果我实施Comparable
,那么我是否可以安全地实施equals
和hashCode
?如同equal
中已包含compareTo
所能完成的任何内容?举个例子,我希望能够比较两个BST的相等性。为此实施hashCode
似乎令人生畏;那么comparable
就足够了吗?
答案 0 :(得分:2)
Comparable通常用于订购商品(如排序),equals用于检查两个商品是否相等。您可以使用可比较的检查相等但不一定。从docs开始,“强烈建议(尽管不是必需的)自然排序与等于”
答案 1 :(得分:2)
equals
(和hashCode
)用于相等测试。 Comparable
接口也可用于等式检查,但实际上它用于排序元素或比较它们的顺序。
也就是说,equals
仅处理相等(类似于==
和!=
),而compareTo
则允许您检查许多不同类型的不等式(类似于{ {1}},<
,<=
,==
,>=
和>
)。因此,如果您的班级有部分或全部订单,您可能需要实施!=
。
the javadocs for Comparable
中简要提及Comparable
与compareTo
之间的关系:
强烈建议,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))。一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:此类具有与equals不一致的自然顺序。”
TreeSet
使用 equals
对您插入的任何内容进行比较和排序,List#sort(null)
使用它来对列表进行排序。它也将在其他地方使用,但这是第一个想到的。
答案 2 :(得分:1)
您应该考虑何时使用该对象。 例如,如果在TreeMap和TreeSet中,那么您将需要Comparable。此外,任何情况下,当您必须对元素(尤其是已排序的集合)进行排序时,必须实现Comparable。在很多情况下都需要覆盖equals和hashcode,其中大部分都是。
答案 3 :(得分:1)
根据javadocs:
此接口对实现它的每个类的对象强加一个总排序。这种排序被称为类的自然排序,而类的compareTo方法被称为其自然比较方法。 可以通过Collections.sort(和Arrays.sort)自动对实现此接口的对象的列表(和数组)进行排序。实现此接口的对象可用作有序映射中的键或有序集中的元素,而无需指定比较器。
当且仅当e1.compareTo(e2)== 0与c1的每个e1和e2的e1.equals(e2)具有相同的布尔值时,C类的自然排序被认为与equals一致。注意null不是任何类的实例,并且e.compareTo(null)应抛出NullPointerException,即使e.equals(null)返回false
简而言之,equals()
和hashcode()
用于比较相等,而Comparable
用于排序
答案 4 :(得分:1)
如果你更新了equals方法,你应该总是更新hashCode,或者当你试图在HashMap或HasSet或类似集合(非常常用)中使用它时,你将为自己或他人设置一个boobytrap。
只有在您使用的接口需要时才需要可比较。您可以将其实现用于排序和排序集合,但在大多数情况下实际上并不需要它。另一种方法是将Comparator传递给排序或集合构造函数。例如,String类有一个不区分大小写的Comparator非常有用,无需创建自己的String类(即String不能扩展。)