3

I read that to use equals() method in java we also have to override the hashcode() method and that the equal (logically) objects should have eual hashcodes, but doesn't that imply reference based equality! Here is my code for overridden equals() method, how should I override hashcode method for this:

@Override    
public boolean equals(Object o)
        {
            if (!(o instanceof dummy))
                return false;
            dummy p = (dummy) o;
            return (p.getName() == this.getName() && p.getId() == this.getId() && p.getPassword() == this.getPassword());

        } 

I just trying to learn how it works, so there are only three fields, namely name , id and password , and just trying to compare two objects that I define in the main() thats all! I also need to know if it is always necessary to override hashcode() method along with equals() method?

Abhishek Nair
  • 167
  • 2
  • 7
  • 2
    Remember 'return 1;' is a completely legal implementation of 'hashcode();' that usually summarizes what you can and can't trust it for :) – Affe Apr 28 '11 at 18:41
  • 1
    Careful! Your sections p.getName() == this.getName() and p.getPassword() == this.getPassword() are not correct (assuming they are strings or non-primitives). You should be using p.getName().equals(this.getName()) and p.getPassword().equals(this.getPassword()). You should also add null checks for accessing those two fields. – Andrew Eisenberg Apr 29 '11 at 05:07

5 Answers5

5

Hashcode equality does not imply anything. However, hashcode inequality should imply that equals will yield false, and any two items that are equal should always have the same hashcode.

For this reason, it is always wise to override hashcode with equals, because a number of data structures rely on it.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
0

In your code, you aren't actually comparing your fields' values. Use equals() instead of == to make your implementation of equal correct.

return (p.getName().equals(this.getName()) && ...

(Note that the above code can cause null reference exceptions if getName() returns null: you may want to use a utility class as described here)

And yes hashCode() would be called when you use some hashing data structure like HashMap,HashSet

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

from Effective Java, by Joshua Bloch

Also See

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
  • "In your code, you aren't actually comparing your fields' values. Use equals() instead of == to make your implementation of equal correct." - If the types of the fields being compared are primitive or immutable (such as String) then `==` will work perfectly fine, and it won't fail if the getters are null. – dj18 May 17 '12 at 15:58
0

You need to override hashCode() when you override equals(). Merely using equals() is not enough to require you to override hashCode().

jprete
  • 3,769
  • 21
  • 24
0

Even though failure to override hashCode() will only break usage of your class in HashSet, HashMap, and other hashCode dependent structures, you should still override hashCode() to maintain the contract described by Object.

The general strategy of most hashCode() implementations is to combine the hash codes of the fields used to determine equality. In your case, a reasonable hashCode() may look something like this:

public int hashCode(){
    return this.getName().hashCode() ^ this.getId() ^ this.getPassword().hashCode();
}
ILMTitan
  • 10,751
  • 3
  • 30
  • 46
-1

The idea with hashCode() is that it is a unique representation of your object in a given space. Data structures that hold objects use hash codes to determine where to place objects. In Java, a HashSet for example uses the hash code of an object to determine which bucket that objects lies in, and then for all objects in that bucket, it uses equals() to determine whether it is a match.

If you don't override hashCode(), but do override equals(), then you will get to a point where you consider 2 objects to be equal, but Java collections don't see it the same way. This will lead to a lot of strange behaviour.

Java Drinker
  • 3,127
  • 1
  • 21
  • 19
  • -1 HashSet does not use hash code to determine if an object is already part of the set. It only uses it to determine where to look. – ILMTitan Apr 28 '11 at 18:47
  • Techinically, you're right, hash to determine the bucket and then checks equal to determine if it is in there... I'll clarify – Java Drinker Apr 28 '11 at 18:56
  • 'it is a unique representation of your object'. No. There is no uniqueness requirement. – user207421 Apr 29 '11 at 00:12
  • Not only is there no uniqueness requirement, but it'd be impossible to have unique 32-bit hash codes for, say, every (128-bit) GUID. Aside from that, there is an expectation that if`a.equals(b)`, then a.hashCode() == b.hashCode()`, meaning there are times when two objects are *expected* to have equal hash codes. – cHao Apr 29 '11 at 02:23