我应该关注这个compareTo/equals/hashCode实现吗?

问题描述:

我正在编写一堆代码,并发现了一些开发人员拥有实现Comparable的DTO的实例。这个DTO有7或8个字段。 CompareTo方法也仅在一个领域已经实现:我应该关注这个compareTo/equals/hashCode实现吗?

private DateMidnight field1; //from Joda date/time library 

public int compareTo(SomeObject o) { 
    if (o == null) { 
     return -1; 
    } 
    return field1.compareTo(o.getField1()); 
} 

同样equals方法无效,基本上可以归结为:

return field1.equals(o.getField1()); 

最后的hashCode方法实现:

return field1.hashCode; 

field1不应该为空,并且在这些对象中将是唯一的(即,我们不应该得到两个对象相同的field1)。

所以,实现是一致的,这是很好的,但我应该担心只有一个字段被使用?这是不寻常的吗?是否可能导致问题或混淆其他开发人员?我正在考虑这些对象的列表被传递并且另一个开发人员使用Map或Set somesort并从这些对象中获取异常行为的场景。任何想法赞赏。谢谢!

+0

在一个切线上... [Joda-Time](http://www.joda.org/joda-time/)的用户应该注意到这个字段是一个类型([DateMidnight`]](http:///www.joda.org/joda-time/apidocs/org/joda/time/DateMidnight.html))现在已被弃用,应该避免。现在适当的类型是[`DateTime`](http://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html),并且调用[`withTimeAtStartOfDate`](http ://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html#withTimeAtStartOfDay--)。 – 2015-07-06 02:22:51

我怀疑这是“首次使用胜利”的情况 - 有人需要对这些对象的集合进行排序或将它们放在哈希映射中,并且它们仅关注日期。最简单的实现方法是按照你说的方式覆盖equals/hashCode并执行Comparable<T>

对于专家分类,更好的方法是在不同的类中实现Comparator<T> ...但遗憾的是,Java没有用于相等性测试的任何等价类。说实话,我认为这是Java收藏的一个主要弱点。

假设这真的是不是“一个自然而明显的比较”,它肯定会在设计方面闻起来...应该是非常小心的文件。

+1

是的,我认为“首先使用胜利”是放置这种设计的好方法,为什么我会感到有些不舒服。你是对的,Comparator似乎更适合这里。 – 2010-12-03 09:14:34

+2

@Chris:你完全适合对它感到不舒服。比较器更适合排序...它只是这样的耻辱有没有办法做到平等:(:(在.NET中有`IEqualityComparer `这是用于此目的。) – 2010-12-03 09:26:44

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

无论是从正确从业务逻辑的角度来看是一个不同的问题。

如果例如field1映射到数据库中的主键是非常有效的。如果FIELD1是一个人的“名字”,我会担心

严格地说,这违反了可比规格:

http://download.oracle.com/javase/6/docs/api/java/lang/Comparable.html

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

同样,它看起来像equals方法将抛出NPE上equals(null)而不是返回false(当然,除非你“煮”出空处理代码)。

是否可能导致问题或混淆其他开发者?

可能,可能不是。这真的取决于如何大你的项目是如何广泛/“可重复使用” /长住你的对象的源代码预期使用:

  • 小型/短命/限量使用==可能不是一个问题。
  • 大/长寿命/广泛使用==反直观的实现可能会导致未来的问题
+2

是的,我做了“煮“out the null处理代码的equals实现,但是由于指出缺少空指针异常的可比较的。不知道那个。 – 2010-12-03 09:17:00

你不应该与它有关,如果FIELD1是真正独特。如果不是,你可能会遇到问题。无论如何,我的建议是做一些单元测试。他们应该显示真相。