embert
asked on
Hash code
Can anybody explain the hash code? how is it related to equals() method?
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.
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.
??
ur class is abit off.... since all objects of Test are equal, u should override hashCode to return the same number...
ur class is abit off.... since all objects of Test are equal, u should override hashCode to return the same number...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
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-----
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-----
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.
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.
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...
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...
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
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
System.out.println("Str2's
}
//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
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.
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.
check out this site for a sample implementation of that.
http://www.ibm.com/java/education/portingc/WellMannered.html#HashCode
http://www.ibm.com/java/education/portingc/WellMannered.html#HashCode
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
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
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;
}
}
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:"+
()+"b`s:"+b.hashCode());
if(a.equals(b))
System.out.println("equals
}
}
class test
{
int i;
public test(int i)
{
this.i=i;
}
}
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.
if anybody here has the right ,everybody will agree that u r not amongst them,nor me.
ASKER
thanks for the discussion.
Lychee: you comments are very helpful, but unfortunately, I cannot accept two answers at the same time.
Lychee: you comments are very helpful, but unfortunately, I cannot accept two answers at the same time.
u can certainly post another question for lychee.
enjoy and happy programming
:-)
enjoy and happy programming
:-)
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.my Object)) 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.equa ls(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.equa ls(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
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.my
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.equa
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.equa
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
i don't have the java source handy (deleted it by mistake :( ) but i think Object would have a native implementation.
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
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
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.
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.
sgoms,
if u get that pls lemme no 2.
thx
if u get that pls lemme no 2.
thx
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...