Java 我应该关注这个compareTo/equals/hashCode实现吗? 我在一组代码中发现了几个例子,其中开发者有一个DTO来实现可比性。此DTO中有7或8个字段。compareTo方法仅在一个字段上实现: private DateMidnight field1; //from Joda date/time library public int compareTo(SomeObject o) { if (o == null) { return -1; } return field1.compareTo(o.getField1()); }

Java 我应该关注这个compareTo/equals/hashCode实现吗? 我在一组代码中发现了几个例子,其中开发者有一个DTO来实现可比性。此DTO中有7或8个字段。compareTo方法仅在一个字段上实现: private DateMidnight field1; //from Joda date/time library public int compareTo(SomeObject o) { if (o == null) { return -1; } return field1.compareTo(o.getField1()); },java,implementation,equals,hashcode,compareto,Java,Implementation,Equals,Hashcode,Compareto,同样,equals方法被覆盖,基本上归结为: return field1.equals(o.getField1()); 最后,hashcode方法的实现是: return field1.hashCode; field1不应为空,并且在这些对象中是唯一的(即,我们不应得到两个具有相同field1的对象) 所以,实现是一致的,这是好的,但是我是否应该担心只使用了一个字段?这不寻常吗?它是否可能导致问题或混淆其他开发人员?我正在考虑这样一个场景,其中传递了这些对象的列表,另一个开发人员使用一个映射

同样,equals方法被覆盖,基本上归结为:

return field1.equals(o.getField1());
最后,hashcode方法的实现是:

return field1.hashCode;
field1
不应为空,并且在这些对象中是唯一的(即,我们不应得到两个具有相同
field1
的对象)


所以,实现是一致的,这是好的,但是我是否应该担心只使用了一个字段?这不寻常吗?它是否可能导致问题或混淆其他开发人员?我正在考虑这样一个场景,其中传递了这些对象的列表,另一个开发人员使用一个映射或某种集合,并从这些对象中获得异常行为。任何想法都值得赞赏。谢谢

我怀疑这是一个“首次使用赢家”的案例——有人需要对这些对象的集合进行排序或将它们放入哈希映射,他们只关心日期。实现这一点最简单的方法是覆盖
equals
/
hashCode
并按照您所说的方式实现
Comparable

对于专家排序,更好的方法是在不同的类中实现
Comparator
。。。但不幸的是,Java没有任何等价的类来进行平等性测试。我认为这是java集合中的一个主要弱点,说实话。


假设这真的不是“一个自然和明显的比较”,它肯定在设计方面有味道。。。而且应该非常仔细地记录。

我认为你不需要担心。这三种方法之间的合同是保持一致的

从业务逻辑的角度来看,它是否正确是另一个问题


例如,如果field1映射到数据库中的主键,则完全有效。如果field1是一个人的“名字”,我会担心严格来说,这违反了可比规范:

请注意,null不是任何类的实例,即使e.equals(null)返回false,e.compareTo(null)也应该抛出NullPointerException

类似地,
equals
方法将在
equals(null)
上抛出NPE,而不是返回
false
(当然,除非您“煮沸”了null处理代码)

它是否可能导致问题或混淆其他开发人员

可能,可能不是。这实际上取决于您的项目有多大,以及您的目标源代码预期使用的/可重用的/长寿命的范围有多广:

  • 小/短期/有限使用==可能不是问题
  • 大型/长寿命/广泛使用==违反直觉的实施可能会导致未来的问题

如果field1真的是独一无二的,你不应该关心它。如果不是,你可能会有问题。无论如何,我的建议是做一些单元测试。他们应该展示真相。

是的,我认为“首次使用胜出”是一个很好的展示这种设计的方式,以及为什么我对它感到有点不舒服。你说得对,比较仪似乎更适合这里。@Chris:你对它感到不舒服是完全正确的。比较器更适合于排序。。。遗憾的是,在平等性方面没有同样的方法:(.NET中有用于此目的的
IEqualityComparer
)+1用于单元测试(遗憾的是,开发人员忽略了为此编写任何显式测试)是的,我做了“煮沸”我们给出了equals实现的null处理代码,但感谢您指出comparable缺少null指针异常。我们不知道这一点。在切线上…的用户应该注意,所讨论的字段属于类型()现在不推荐使用,应该避免使用。现在合适的类型是,根据需要调用。