我正在QA中编写一堆代码并找到了几个实例,其中开发人员有一个实现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());
最后哈希码方法的实现是:
return field1.hashCode;
field1
永远不应为null,并且在这些对象中是唯一的(即我们不应该得到两个具有相同field1
的对象)。
因此,实现是一致的,这是好的,但是我应该担心只使用一个字段吗?这不寻常吗?是否可能导致问题或混淆其他开发人员?我正在考虑这样的场景,其中传递了这些对象的列表,另一个开发人员使用Map或Set of somesort并从这些对象获得异常行为。任何想法都赞赏。谢谢!
答案 0 :(得分:5)
我怀疑这是“第一次使用胜利”的情况 - 有人需要对这些对象的集合进行排序或将它们放在哈希映射中,并且他们只关心日期。实现这一目标的最简单方法是覆盖equals
/ hashCode
并按照您所说的方式实施Comparable<T>
。
对于专家排序,更好的方法是在不同的类中实现Comparator<T>
...但遗憾的是,Java没有任何等效的等级测试类。我认为这是Java集合中的一个主要弱点,说实话。
假设这真的不是“一个自然而明显的比较”,它在设计方面肯定闻起来......而且应该非常仔细地记录。
答案 1 :(得分:2)
严格来说,这违反了可比较规范:
http://download.oracle.com/javase/6/docs/api/java/lang/Comparable.html
请注意,null不是任何类的实例,并且e.compareTo(null)应抛出NullPointerException,即使e.equals(null)返回false。
同样地,看起来equals
方法会在equals(null)
上抛出NPE,而不是返回false
(除非您将“煮沸”掉掉空处理代码)。
是否可能导致问题或混淆其他开发人员?
可能,可能不是。这实际上取决于您的项目有多大以及您希望使用的对象源代码的广泛/“可重用”/长期存在:
答案 2 :(得分:2)
如果field1 非常独特,你不应该关心它。如果不是,您可能会遇到问题。无论如何,我的建议是做一些单元测试。他们应该表明真相。
答案 3 :(得分:1)
我认为你不必担心。三种方法之间的合同是保持的,并且是一致的。
从业务逻辑的角度来看它是否正确是一个不同的问题。
如果是field1映射到数据库中的主键,它完全有效。如果field1是一个人的“名字”,我会担心