Java 是否可以/应该编写一个与Object';s等于法

Java 是否可以/应该编写一个与Object';s等于法,java,equals,comparator,Java,Equals,Comparator,我有一个对象,Foo,它从object继承了默认的equals方法,我不想覆盖它,因为引用相等是我想要使用的身份关系 我现在有一个特定的情况,我现在想根据一个特定的字段来比较这些对象。我想编写一个比较器,FooValueComparator,来执行这个比较。但是,如果我的FooValueComparator每当两个对象对此特定字段具有相同的值时返回0,则它与从该对象继承的equals方法以及由此产生的所有问题不兼容 我想做的是让FooValueComparator首先比较两个对象的字段值,然后比

我有一个对象,
Foo
,它从
object
继承了默认的
equals
方法,我不想覆盖它,因为引用相等是我想要使用的身份关系

我现在有一个特定的情况,我现在想根据一个特定的字段来比较这些对象。我想编写一个比较器,
FooValueComparator
,来执行这个比较。但是,如果我的
FooValueComparator
每当两个对象对此特定字段具有相同的值时返回0,则它与从该对象继承的equals方法以及由此产生的所有问题不兼容

我想做的是让
FooValueComparator
首先比较两个对象的字段值,然后比较它们的引用。这可能吗?可能会导致哪些陷阱(例如,内存位置的更改导致
Foo
对象的相对顺序发生更改)


我希望比较器与equals兼容的原因是,我希望可以选择将其应用于
SortedSet
对象的
Foo
集合。我不希望
SortedSet
拒绝我试图添加的
Foo
,因为它已经包含具有相同值的不同对象。

这在以下文档中描述:

比较器c对一组元素
S
施加的排序称为与equals一致,当且仅当
c.compare(e1,e2)=0
S
中的每个
e1
e2
具有相同的布尔值

当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元素(或键)一起使用。如果c对S施加的顺序与equals不一致,则排序集(或排序映射)的行为将“奇怪”。特别是排序集(或排序映射)将违反集合(或映射)的一般约定,它的定义是平等的

简而言之,如果
比较器
的实现与
equals
方法不一致,那么您应该知道自己在做什么,并且您要对这种设计的副作用负责,但使实现与
对象#equals
一致不是强加的。不过,要考虑到最好这样做,以免给将来维护系统的编码人员造成混乱。类似的概念适用于实施
可比

JDK中的一个例子可以在中找到,它在javadoc中明确指出此方法与
BigDecimal#equals
不一致



如果您打算使用
分类数据集
,那么您可能使用了错误的方法。我建议改用
SortedMap
(或者
SortedMap
,以防同一个键没有相等元素)。这可能需要做更多的工作,但它为您提供了对存储在结构中/从结构中检索到的数据的更多控制。

这在以下文档中进行了描述:

比较器c对一组元素
S
施加的排序称为与equals一致,当且仅当
c.compare(e1,e2)=0
S
中的每个
e1
e2
具有相同的布尔值

当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元素(或键)一起使用。如果c对S施加的顺序与equals不一致,则排序集(或排序映射)的行为将“奇怪”。特别是排序集(或排序映射)将违反集合(或映射)的一般约定,它的定义是平等的

简而言之,如果
比较器
的实现与
equals
方法不一致,那么您应该知道自己在做什么,并且您要对这种设计的副作用负责,但使实现与
对象#equals
一致不是强加的。不过,要考虑到最好这样做,以免给将来维护系统的编码人员造成混乱。类似的概念适用于实施
可比

JDK中的一个例子可以在中找到,它在javadoc中明确指出此方法与
BigDecimal#equals
不一致



如果您打算使用
分类数据集
,那么您可能使用了错误的方法。我建议改用
SortedMap
(或者
SortedMap
,以防同一个键没有相等元素)。这可能需要做更多的工作,但它为您提供了对结构中存储/检索的数据的更多控制。

对于给定的类,您可能有多个比较器,即每个不同的字段
在这种情况下,不能重复使用equals。因此答案是不一定是。但是,如果集合存储在已排序的(地图或树)中,并且comperator用于确定元素在该集合中的位置,则应使它们一致


有关详细信息,请参阅。

对于给定的类,您可能有多个比较器,即每个比较器对应不同的字段
在这种情况下,不能重复使用equals。因此答案是不一定是。但是,如果您的收藏存储在已排序(地图或树)中,并且comperator用于