3

我正在对一堆代码进行质量检查,并发现了几个例子,其中开发人员有一个实现 Comparable 的 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());
}

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

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

最后hashcode方法实现是:

return field1.hashCode;

field1永远不应该为 null 并且在这些对象中是唯一的(即我们不应该得到两个具有相同 的对象field1)。

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

4

4 回答 4

5

我怀疑这是“首次使用获胜”的情况——有人需要对这些对象的集合进行排序或将它们放入哈希映射中,而他们只关心日期。实现它的最简单方法是以您所说的方式覆盖equals/hashCode并实现。Comparable<T>

对于专业排序,更好的方法是Comparator<T>在不同的类中实现......但不幸的是,Java 没有任何等价类测试。老实说,我认为这是 Java 集合中的一个主要弱点。

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

于 2010-12-03T08:03:59.253 回答
2

严格来说,这违反了 Comparable 规范:

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

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

同样,看起来该equals方法将抛出 NPEequals(null)而不是返回false(当然,除非您“煮沸”了 null 处理代码)。

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

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

  • 小/短寿命/有限使用==可能不是问题。
  • 大/长期/广泛使用==违反直觉的实现可能会导致未来的问题
于 2010-12-03T08:09:08.957 回答
2

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

于 2010-12-03T08:24:09.687 回答
1

我认为你不必担心。三种方法之间的约定保持不变并且是一致的。

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

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

于 2010-12-03T08:05:18.567 回答