问题
Standard object modelling identifies attributes, aggregates and associations of objects. You must conform to several requirements when implementing the equals() method of a class. There is plenty of advice available on how to write this method, including pitfalls to avoid. But I couldn't find any advice indicating whether you should or should not examine associations when implementing equals()
. It is clear to me that you should examine attributes and aggregates.
Should you examine associated objects in equals()
? That is, should equality depend on associated objects?
回答1:
While I think it is generally a good idea to avoid basing equality on associations, I would argue that this does not apply in all cases. While it is a good rule of thumb, there are likely a number of cases where this rule breaks completely.
It is entirely dependent on the domain and what it means for two objects to be equal. For example:
If you have a cohort of students, taught by a teacher, you could determine equality by requiring that another cohort must contain the same students be (pair-wise equal) and be taught by the same teacher. In that case, the cohort's equality is strictly dependent on each of it's pieces being equal.
回答2:
Equality should not depend in any way on associated objects, therefore equals()
should not examine associates. It should not even depend on the identity of associates, or even whether an object has an association. I'm surprised that this advice is not explicitly stated often enough for me to have found it.
From an object modelling point of view, it is natural to consider two things with different associations to be equivalent. If a mad scientist were to create an exact duplicate of me, we would say the doppelgänger and I were "the same" (equivalent), even though we had different fathers (different fathered-by associations). The doppelgänger might not even have a father (if the scientist were more mad physicist than mad biologist).
Examining associations introduces practical problems. There is the danger of bi-directional associations (spouse-of, for example) causing infinite loops. There is the performance hit of indirect associations requiring examination of potentially all objects in the working-set: if your
Person
objects have parent-of and child-of associations,Person.equals()
would actually tell you whether family trees were equivalent.
回答3:
in general perhaps not. but how about a car that has frame, body, engine, wheels etc. one could consider different implementations of equals.
回答4:
Short answer: make equals() do what you need it to do. But be careful.
Where the class may be used as a key in a HashMap
(or stored in a HashSet
), equals() must be constant for the time that it's in the map. This suggests that, in order to avoid a lot of analysis and/or bugs, classes used as HashMap keys should restrict equals()
to effectively immutable fields - including associations.
You also must ensure that any equals-included associated object has a similarly immutable-for-contained-scope equals() implementation, and doesn't do an equals() back on the original object, causing runaway recursion.
来源:https://stackoverflow.com/questions/7602089/examining-associated-objects-in-equals