Should mutable collections override equals and hashCode?

You should override equals and hashCode if your class should act like it were a value type. This usually is not the case for collections.

You should override equals and hashCode if your class should act like it were a value type. This usually is not the case for collections. (I don't really have much Java experience.

This answer is based on C#. ).

The problem of deep and shallow equals is bigger than Java; all object oriented languages have to concern themselves with it. The objects that you add to the collection should override equals and hash code, but the default behavior built into the abstract implementation of the collection interface suffices for the collection itself.

3 @duffymo: +1... But all OO languages didn't make the same mistake that the Java creators did: putting equals and hashCode at the top of the OO hierarchy as if it made any sense (it doesn't). There should have been an Equalable (just made that up) interface or somethin'. And, no, I'm not a Java hater but a Java fanboy :) – SyntaxT3rr0r Mar 9 at 14:28 I don't agree that it's a mistake.

You need identity for all objects; that's why it's in java.lang.Object. "Equalable"? I think that's a mistake, but that's just me.8) – duffymo Mar 9 at 14:51 1 @duffymo: but identity has nothing to do with the concept of equals and hashCode.It simply is incompatible with OO and that's it.

There's a great article on the Java equals/hashCode SNAFU (a conversation between Bill Venners and the creator of Scala IIRC) and, once again, it's explained in "Effective Java". It is broken for any non-final class and that is a fact. The concept is broken for mutable objects and that is also a fact.

At one point you have to wonder if their presence at the top of the OO hierarchy still makes any sense or not. – SyntaxT3rr0r Mar 9 at 15:10 Really? I thought it did, but I'll read your citations.

– duffymo Mar 9 at 15:24 @duffymo: what do you mean? You thought equals and hashCode had to do with identity? How could it?

The identity issue exist in a lot of languages. Identity is a very important concept in FP languages for example (like, say, Clojure). But equals and hashCode are Java-idiosynchrasies that makes no sense with mutability and makes even less sense with non-final classes.

And of course there are ways to have the "identity" concept in Java without ever using equals and hashCode... – SyntaxT3rr0r Mar 9 at 16:39.

I think the bigger question is what should happen if someone attempts to add an instance of your FredCollection to a Set twice. FredCollection c = ... set. Add(c); set.

Add(c); Should the size() of set be 2 or 1 after this? Will you ever have a need to test the "equality" of two different instances of FredCollection? I think the answer to this question is more important at determining your equals()/hashcode() behavior than anything else.

Can we please have an illustration of working example so that it can handy for further reference. – Deepak Mar 9 at 16:46.

It's the same as with any mutable class. When you insert an instance into a HashSet and then call a mutating method, you will get into trouble. So, my answer is: Yes, if there's a use for it.

You can of course use an immutable Wrapper for your Collection before adding it to the HashSet.

This is not just an issue for collections, but for mutable objects in general (another example: Point2D). And yes, it is a potential problem that Java programmers eventually learn to take into account.

You should not override equals and hashCode so that they reflect the mutable member. There are two reasons: first: because this would break the contract of hash code: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer... @see: JavaDoc Object#hashCode() second: technical vs. business logic If you break that requirement HashSet and HashMap and every component based on them will probaly not work correct. The second reason not to do this: is more my personal point of view.

I think hash code and equals are technical terms that should not be used to implement business logic. Imagine: you have two Objects (not only Collections) and ask if they are equals, then there are two different ways to answer them: technical: the are equals if they represent the same object, which is different from being the same object (if you think of proxies, serilization, remote stuff...) bussines logic: they are equals if the look the same (same attribute) – the important thing here is, that there is not the holy one definition of equality even to the same class in even one application. (Sample question: when are two stones equals?)) But because equals is used by technical stuff (HashMap), you should implement it in a technical way, and build the business logic related equals by something else (something like the comparator interface).

And for your collection it means: do not override equals and hashCode (in a way that breaks the technical contract).

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions