当我查看 Java Object Ordering 时教程,文章的最后一节“比较器”让我有点困惑。
通过定义一个类 Employee
,它本身可以通过员工姓名进行比较,教程不会显示此类是否已覆盖 equals
方法。然后它使用自定义的 Comparator
其中员工按资历排序以对员工列表进行排序,我可以理解。
然后本教程解释了为什么这不适用于像 TreeSet
这样的排序集合。 (a SortedSet
),原因是:
it generates an ordering that is not compatible with equals. This means that this Comparator equates objects that the equals method does not. In particular, any two employees who were hired on the same date will compare as equal. When you're sorting a List, this doesn't matter; but when you're using the Comparator to order a sorted collection, it's fatal. If you use this Comparator to insert multiple employees hired on the same date into a TreeSet, only the first one will be added to the set; the second will be seen as a duplicate element and will be ignored.
现在我很困惑,因为我知道 List
允许重复元素,而 Set
不基于 equals
方法。所以我想知道当教程说 Comparator
生成的顺序与 equals 不兼容时,这是什么意思?它还说'如果您使用此比较器将同一日期雇用的多个员工插入到 TreeSet 中,则只会将第一个添加到集合中;第二个将被视为重复元素并将被忽略。我不明白使用 Comparator
会如何影响原始 equals
方法的使用。我想我的问题是在这种情况下如何生成和排序 TreeSet
以及何时使用 compare
和 equals
方法。
最佳答案
So I wonder when the tutorial says the ordering generated by the Comparator is not compatible with equals, what does it mean?
在此示例中,Comparator
仅根据资历比较两个 Employee
对象。此比较不以任何方式使用 equals
或 hashCode
。请记住,当我们将此 Comparator
传递给 TreeSet
时,该集合会将 Comparator
的任何结果 0 视为相等。因此,如果任何 Employee
共享开始日期,则只会添加一个,因为集合认为它们是相等的。
最后:
I think my question is how the TreeSet will be produced and sorted in this case and when the compare and equals methods are used.
对于 TreeSet
,如果给定了 Comparator
,它会使用 compare
方法来确定对象的相等性和顺序。如果未给出 Comparator
,则集合使用被排序对象的 compareTo
方法(它们必须实现 Comparable
)。
Java规范之所以说使用的compare
/compareTo
方法必须符合equals
,是因为Set
规范使用了 equals
,尽管这种特定类型的 Set
,即 TreeSet
,使用的是比较。
如果您曾经从某个方法实现中收到一个 Set
,您可以预期 equals 定义的
方法。但是,由于 Set
中没有重复的对象TreeSet
不使用此方法,开发人员必须小心确保比较方法产生与 equals
相同的相等性。
关于已排序集合的 Java 对象排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37925531/