Howdy -- just wanted to put in a quick summary of the whole hashcode() / equals() thing.
Remember that the == comparison tells you *only* if two references are referring to the same (single) object on the heap.
Dog d = new Dog();
Doc c = d;
c == d because there's only one Dog, and they both refer to it. The == looks ONLY at the bit
patterns in the two variables. The bits are the same, or they're not. If they're the same, it can be ONLY because the two references refer to the same object.
So if == tells us that two references refer to the same object, but what happens if we want to know if two DIFFERENT objects are "meaningfully" the same? Then we have to use equals().
If you do not override equals(), the version of the equals methiod that you inherit from Object simply does an == comparison. In other words, there is no difference between == and equals() unless the equals() method is overidden.
Who decides when two objects are meaningfully the same? For your own classes, YOU do. Typically, you would do this by comparing the key instance variables -- the ones that *matter* -- of two objects, and if they're the same, then your equals method will return true. But that's up to you based on what your class really represents.
For some of the classes in Java -- String and the wrappers (Integer, Double, etc.-- the equals method has been overridden so that you can have two DIFFERENT objects, but if both contain the same value for their most important instance variable(s) (like, if two Integer objects both have a value of 12), they are considered "equal".
What good is this? So that two different objects can still "match". Most importantly, if you want to use the object in a collection that uses hashing. For example, if you want to store an object in a HashMap, you store both the object itself AND another object that represents the unique ID or "key". But in order to find that stored object again, you have to provide the "key" object, and the collection will then return the *real* object stored with that key (think of the "key" as an object that represents a unique ID for the *real* object you're trying to store). So if you can never have two different objects that can be equal, then watch what happens... you stick an object in a HashMap with an associated "key" object. Then you try to get the object back out again by providing the "key" -- only, you no longer HAVE the original key object, so you make one that is identical... or so you think. But when you give it to the HashMap, the HashMap gives you that confused look and says, "I've never seen that key before in my life." In other words, the object that you THINK represents the key will NOT be considered a 'match' by the HashMap. Because the HashMap has to be certain that the objects are equal.
Then what about hashcode? Well, if two objects are truly equal, then their hashcodes MUST be equal. It is considered impossible (although you could incorrectly write your code this way) for two objects that are equal (using equals()) to have *different* hashcodes.
But... you can certainly have objects with the SAME hashcode that still are not equal. If you have a lot of objects in a collection with the same hashcode, but which are not equal, it just means that your hashing is not very efficient (for example, it is LEGAL to write a hashcode method that simply returns the very same integer (like, 42) for EVER object of that type. It's legal, but terribly inefficient and you might as well not use this class for anything related to hashing.)
So bottom line:
Equality is most important, but if you override equals() you MUST override hashcode in such a way that two objects who are considered equal (because equals() returns true) will also have identical hashcode values.
But you can have two objects with the SAME hashcode who still are not equal.
How do you do this? By using the same important instance variables to compute the hashcode that you used to compare in your equals method. For example, if you look at the X and Y variables of an object to determine if they are equal or not, then your hashcode algorithm should use X and Y as part of its calculation. So that if X and Y change in a way that makes the two different objects equal, then the hashcode values will reflect that.
Gee, I said this was a summary didn't I? Well, sorry, I got carried away. Or as some famous person once said, "I would have written a shorter letter if I'd had more time..." (or something like that).
Cheers,
Kathy : )