2011-09-29 91 views
-2

标准对象建模标识对象的属性,聚合和associations。在实施课程的equals()方法时,您必须符合几个要求。有很多关于如何编写此方法的建议,包括pitfalls to avoid。但我找不到任何建议,指出在执行equals()时是否应该检查关联。我很清楚你应该检查属性和聚合。在equals中检查关联的对象()

如果您检查equals()中的关联对象?也就是说,平等应该依赖于关联的对象吗?

+0

对象关联可以有循环引用,这可能会导致问题:http://stackoverflow.com/questions/8863308/implementing-equals-and-hashcode-for-objects-with-circular-references-in-java – Raedwald

回答

1

虽然我认为避免基于关联的平等是一个好主意,但我会认为这并不适用于所有情况。虽然这是一个很好的经验法则,但有很多情况下这个规则完全可以打破。

它完全依赖于域以及两个对象相等的含义。例如:

如果你有一群由老师​​教授的学生,你可以通过要求另一个人必须包含同一个学生be(成对平等)并由同一位老师教授来确定平等。在这种情况下,队列的平等严格依赖于它的每一块是平等的。一般来说也许并不是

+0

很好的例子。我不知道它可以推广吗?实际上有两种不同的关联? – Raedwald

+0

......或者这种关系是否应该被认为是一种“弱集合”。 – Raedwald

0

平等不应该以任何方式依赖于关联的对象,因此equals()不应该检查关联。它甚至不应该依赖于员工的身份,甚至不依赖于对象是否有关联。我很惊讶这个建议没有被明确地表述出来,以至于我没有找到它。

  • 从对象建模的角度来看,很自然地认为具有不同关联性的两件事是等价的。如果一个疯狂的科学家为我创造一个精确的副本,即使我们有不同的父亲(不同的父亲协会),我们会说doppelgnger和我是“相同的”(等效)。如果科学家比疯狂的生物学家更疯狂的物理学家,那么这个人可能甚至没有父亲。

  • 检查关联引入了实际问题。例如bi-directional associations配偶 - 例如)存在导致无限循环的危险。有需要在工作集可能是所有检查对象的间接关联的性能损失:如果您Person对象有及家长的儿童的协会,Person.equals()实际上会告诉你的家人树木是否等同。

+0

I会争辩说,这种说法并不适用于所有情况。虽然这是一个很好的经验法则,但有很多情况下这个规则完全可以打破。它完全依赖于域以及它对于两个对象的平等意味着什么。如果我的对象的部分相等要求它引用另一个对象,这个对象也等于我的同一对象,那么这个要求就是你的规则的反例。 – cdeszaq

+0

@cdeszaq你能提供一个具体的例子吗? – Raedwald

+0

查看我的回答。 – cdeszaq

0

。但有车架,车身,发动机,车轮等车可以考虑不同的平等实施。

+0

我想说,护理是这些组件的集合,而不是汽车与他们相关联。 – Raedwald

0

简短的回答:使equals()做你需要它做的事情。不过要小心。

如果该类可以用作HashMap(或存储在HashSet中)中的键,那么equals()在地图中的时间必须是常量。这表明,为避免大量分析和/或错误,用作HashMap键的类应该将equals()限制为有效的不可变字段 - 包括关联。

您还必须确保任何等号包含的关联对象具有类似的不可变范围的equals()实现,并且不会在原始对象上执行equals(),从而导致失控递归。

+0

“有效的不可变字段”:在构造函数中设置关联(例如,双向关联)可能会很麻烦,所以这是使用关联的一个理由。 – Raedwald

+0

我不同意。 “平等”应该反映对象的平等。基于可变字段定义相等性就好了。无论使用什么对象作为关键字来确保它的值不会随着时间而改变(或者不在基于散列的集合中使用它)。使用你的逻辑,我们绝不应该在可变对象上定义相等性,因为它可以用在基于散列的集合中。 –

+0

@Steve,我认为你误解了,或者我写得很差,或者两者都写......在我写了“restrict equals()to effective immutable fields”的地方,它是在前面的句子的上下文中 - 对象被保存在一个HashMap。我更新了这句话,以确保这一点很清楚。这是否反映你的反对意见? –