

How To Write an Equality Method in Java - trjordan
http://www.artima.com/lejava/articles/equality.html

======
russell
> Here are four common pitfalls that can cause inconsistent behavior when
> overriding equals:
    
    
       1. Defining equals with the wrong signature.
       2. Changing equals without also changing hashCode.
       3. Defining equals in terms of mutable fields.
       4. Failing to define equals as an equivalence relation.
    

I have to call this a must read. Writing equals is straight forward, but there
are are many ways to go wrong. In fact the article doesnt go far enough,
because complex objects often have different levels of equality: Is it the
same object, by UID or some immutable field? Is it equal by some subset of the
contents? Is it equal by some classification or hierarchy?

EDIT: by different kinds of equality, I mean such things as equalByContent for
mutable fields or equalByLocation.

~~~
brown9-2
Bloch's Effective Java is the true must read here, 80% of this article simply
re-iterates what was already published there (and in other places) already.
The author just adds this "canEquals" idea, which sounds like it might become
annoying and hard to maintain if you have more than a small handful of
subclasses to deal with.

------
amalcon
Technically it's not a problem to define equals based on mutable data, but it
is a problem to define hashCode based on mutable data. One could have a class
with, say, an immutable X and a mutable Y. You probably want to check equality
based on both X and Y, but hash based on X.

Or, y'know, just don't use mutable data for keys. I thought that was what
people were supposed to do anyway.

~~~
stcredzero
Maybe languages should have special interfaces for things that can be
dictionary keys? That way, when someone implements that interface, you are
certifying that the object is suitable for being a key.

~~~
pmjordan
C++'s std::[unordered_]{map|multimap|set|multiset} containers all make _const_
copies of keys. Of course, this being C++ you can wiggle out of this
requirement (e.g. using the _mutable_ keyword) but you have to be pretty
insistant about it.

On the other hand, C++ containers have all sorts of other problems (iterator
invalidation to name one)...

C# has the value type concept, but I don't think it's enforced on container
keys.

------
febeling
I find it disappointing to see such an discussion around a Java quirk voted up
here. These things are in every Java book since at least 6 years, and Java has
not gained in interestingness since. Also, Eclipse tells you that with a
warning if you want.

Sorry to be so negative.

------
req2
> In fact, it's well known in Java that hashCode and equals should always be
> redefined together.

Shouldn't there be some sort of in-language capacity to address this? A
"Warning: equals and hashCode not codefined" seems like it would help.

~~~
stcredzero
How would you know if the inherited hashCode is correct or not? Would you just
assume that it isn't? That would result in lots of redundantly defined
hashCode methods. Not sure that's better.

~~~
req2
I'm over my head here, but this is the naive idea that I imagined -

You could add two keywords like /notice/ and /keep/. If a parent class's
function definition of foo has /notice bar/, overrides of foo could allow the
new class to inherit bar with /keep bar/, or warn if neither a keep statement
or an override are present.

