• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 562
  • Last Modified:

Hash code

Can anybody explain the hash code? how is it related to equals() method?
0
embert
Asked:
embert
  • 6
  • 5
  • 4
  • +3
1 Solution
 
_lychee_Commented:
Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

hashCode obeys:
1. hashCode of an object doesn't change
2. hashCode of 2 objects that are equal() must be the same

and hashCode is hopefully different for 2 different objects...
0
 
jsridharCommented:
Extracts from java.lang.Object

Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

The general contract of hashCode is:

1. 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, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

2. If two objects are equal according to the equals(Object) method, then calling the <code>hashCode</code> method on each of the two objects must produce the same integer result.

3. It is not required that if two objects are unequal according to the java.lang.Object.equals method, then calling the hashCode method on each of the two objects must produce distinct integer results.  However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java programming language.)

-------------

As you can see last para says that, the current implementation of JVM from Sun will give return integers which are actually the address of the object in memory.

So, theoritally the rules are laid for how hashCode should function, in actuals, it is implemented as described above.

The following program demonstrates the above:
public class Test {

  public boolean equals(Object obj) {
    return true;
  }

  public static void main(String args[]) {
    Test t1 = new Test();
    Test t2 = new Test();
    System.out.println("T1's hash code: " + t1.hashCode());
    System.out.println("T2's hash code: " + t2.hashCode());
  }
}

js.
0
 
_lychee_Commented:
??
ur class is abit off.... since all objects of Test are equal, u should override hashCode to return the same number...
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
sgomsCommented:
public int hashCode()

Hashtable uses a special value called a hash code . The hash code is a
way to take some information in the object in question and turn it into a “relatively unique” int for that object. All objects have a
hash code, and hashCode( ) is a method in the root class Object. A Hashtable takes the hashCode( ) of the object and uses
it to quickly hunt for the key.

Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

The general contract of hashCode is:

* Whenever hashCode of the same object is requested it should consistently return the same integer, provided information given to the equals() method is not altered.
  This value need not remain the same from one application to another. i.e hasCode of a String object "Data" need not be the same from application
      myFrame1 to myFrame2.
      
* If 2 objects are equal according to equals() method of Object then the hashCode should remain the same.
  For ex:
      String str1=new String("Element");
      String str2=new String("Element");
      Then str1.equals(str2) is true. hence the hashCode of str1 & str2 will be the same.

* It is not abolutely neccassary to have unique hashCode if  2 objects are not equal according to equals() method.
  Although it'll improve the performance of the Hashtable if unique codes are generated.


As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)


-sgoms
0
 
jsridharCommented:
A small change in sgoms comments:

The reason why str1 and str2 has same hashCode is not bcos of sr1.equals(str2). The foll program demonstrates it:

public class Test {

  public boolean equals(Object obj) {
    return true;
  }

  public static void main(String args[]) {
    Test t1 = new Test();
    Test t2 = new Test();

    System.out.println("t1's hashCode: " + t1.hashCode());
    System.out.println("t2's hashCode: " + t2.hashCode());
    System.out.println("value of equals() fn: " + t1.equals(t2));
  }
}

Althought the equals of the two objects returns true, the hashCode are not same.

js.
0
 
jsridharCommented:
lychee:

not necessary. bcos the actual implementation in JVM is:

-----extract from spec-----
This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not ...
-----extract from spec-----
0
 
jsridharCommented:
lychee:

not necessary. bcos the actual implementation in JVM is:

-----extract from spec-----
This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not ...
-----extract from spec-----

js.
0
 
_lychee_Commented:
huh?
the contract of hashCode is such that if equals remains true, the hashCode must be equal....

in ur Test class, u override equals to return true for any objects of type Test... therefore u must override hashCode to return the same integer for all objects... otherwise the default hashCode will be used which, in general, does not give the same integer for 2 objects...

think of it as
equals => hashCode equal
but not the converse...
0
 
sgomsCommented:
Yes in the class Test hasCode needs to be overridden.
In case of equals function shud'nt u chk for,

if(obj!=null && obj instanceof Test)
  return true;
else
  return false;

I'd like to know how to overdide hashCode to return a unique value. does it have to be a native implementation?
___________________________________________________________

The following example uses String class which has overridden equals & hashCode.


class hashCodeTest{

    public static void main(String args[]){
              String str1=new String("Element");
                  String str2=new String("Element");
          System.out.println("Str1's hash code: " + str1.hashCode()); //str1.equals(str2) is true
          System.out.println("Str2's hash code: " + str2.hashCode());
            }
    //String calcuates the hashCode by returning a value s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]                

}

The above function returns the same hashCode for str1 & str2
0
 
sgomsCommented:
js,

As equals() needs to be overridden to return true for same objects hashCode needs to be overridden to return same values if equals() is true.
0
 
mbormannCommented:
check out this site for a sample implementation of that.
http://www.ibm.com/java/education/portingc/WellMannered.html#HashCode
0
 
sgomsCommented:
exactly js,

the hasCodes ought to be same according to spec.
" If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two
 objects must produce the same integer result. "

so if t1.equals(t2) is true then the hasCode() must return the same integer value.

It does not return the same value 'cos you have not overridden it.

String class overrides hasCode to return a int,
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]  

-sgoms
0
 
chintal_studCommented:
hashCode() generates a integer value according to the procedure it uses.

the hashCode() in Object class return a unique value for each object(I mean object reference).

if two objects are refernce to same then they will have same hashCode.

the hashcode() in Object follows a procedure which is based on memeory references to genreate the hashcode unique value.

the hashcode() and equals() infact uses the memeory refernces as the underlying mechanism to do the things.
//go through the following code thimngs will be clear.
insert one of hte three statemnets at the
//expected line comment            in the program
test c=new test(2);
test b=new test(1);
test b=a;


public class trial2
{
      
public static void main(String args[])
{
   test a=new test(1);

//expected one of the above lines here



   System.out.println("a`s:"+a.hashCode
   ()+"b`s:"+b.hashCode());            
   if(a.equals(b))                
     System.out.println("equals");


      
      }
}

class test
{
      int i;
      public test(int i)
      {
            this.i=i;
      }
}



 
0
 
mbormannCommented:
so what did u do different that u get to 'propose' answer?

if anybody here has the right ,everybody will agree that u r not  amongst them,nor me.
0
 
embertAuthor Commented:
thanks for the discussion.

Lychee: you comments are very helpful, but unfortunately, I cannot accept two answers at the same time.  
0
 
mbormannCommented:
u can certainly post another question for lychee.
enjoy and happy programming
:-)
0
 
sgomsCommented:
chintal_stud,
Please do not post ur comments as answer when there is a discussion going on.
Moreover your comments are way off the mark. please be absolutely sure abt ur statements b4 locking the question. No offense meant.
____________________________________________________________

hasCode() & equals() should be implemented in a class.
Thanks to mbormann, Java Cookbook shows an excellentway to implement equals & hashCode.
I went thru quite a few Java source files(String, Integer, Data, Calendar...) which has hashCode() implemented in them.
None of them had a native implementation. Is there any Java class that does native implementationof hashCode() ?

I have modified the Test class, so that its got a few varaibles in it(primitive int, boolean, String object).
this is how the equals() & hashCode() shud be implemented.

public class Test {
            private int myPrimitive=1;
            private boolean myBoolean=true;
            private String myObject = new String("String");
            
            public boolean equals(Object obj) {
             if (this == obj) return true;
             if (obj == null || getClass() != obj.getClass()) return false;
             Test other = (Test)obj;
     if (myPrimitive != other.myPrimitive) return false;
     if (!myObject.equals(other.myObject)) return false;
             return true;
            }
            public int hashCode(){
                int hash=0;
                        hash = hash*37 + myPrimitive;
                        hash = hash*37 + (myBoolean ? 1:0);
                        hash = hash*37 + myObject.hashCode();
                        return hash;
            }
            
            public static void main(String args[]) {
              Test t1 = new Test();
                  Test t2 = new Test();
                  System.out.println(t1.equals(t2)); //when equals() returns true the hashCode is same
                  System.out.println("T1's hash code: " + t1.hashCode());
              System.out.println("T2's hash code: " + t2.hashCode());
                                    
                  t1.myObject="String1";
                  t2.myObject="String2";
                  System.out.println(t1.equals(t2)); //when equals() returns false the hashCode alters. though it necessarily need not be different
                  System.out.println("T1's hash code: " + t1.hashCode());
              System.out.println("T2's hash code: " + t2.hashCode());
                  
            }
}
___________________________________________________________
Output:

true
T1's hash code: -1808117329
T2's hash code: -1808117329
false
T1's hash code: -217104482
T2's hash code: -217104481

the URL suggested by mbormann is super..please check that out for a more elaborate explanation!

-sgoms
0
 
_lychee_Commented:
i don't have the java source handy (deleted it by mistake :( ) but i think Object would have a native implementation.
0
 
sgomsCommented:
lychee,

the Object.java file contains just,
    public native int hashCode();
no implementation.

Iam yet to locate a Java class that has a native implementation for hashCode.

If you can point me to it that'd be great!
Thanks,
sgoms
0
 
jsridharCommented:
iam too late to add the comments, but still:

i was trying show:

1. Overriding equal class alone will not cause a compiler error or runtime error.
  This means overriding equals alone is syntactically and semantically correct. My example was trying to analyze this point.

2. The spec or the VM implementation does not IMPOSE a "restriction" that if equals method is overridden, then hashCode method also should be overridden.

3. The spec for hashCode function says: "Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.HashTable"
  It means, this method is a kind of Adapter method for a particular job. Just like adapter classes are dummy wrappers, these methods can also be dummy calls and implemented as and when needed.

I agree with the guys here in the fact that it is a good programing practice to "always implement this function with the CONTRACT intact"

js.
0
 
mbormannCommented:
sgoms,
if u get that pls lemme no 2.
thx
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 6
  • 5
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now