equals
and hashCode
method must be consistent, which means that when two objects are equal according to equals
method their hash
In the following code:
public boolean equals(Object oo) {
if(oo instanceof Hashvalue)
HashValue hh = (HashValue) oo;
if (this.x == hh.x)
return true;
else
return false;
}
there are a couple of issue: 1. Hashvalue is not recognised by your compiler. It should be "HashValue" 2. hh is out of scope once out of if-block. Hence, compiler error.
You can change your program to following and it will work:
public boolean equals(Object oo) {
if(!(oo instanceof Hashvalue))
return false;
HashValue hh = (HashValue) oo;
if (this.x == hh.x)
return true;
else
return false;
}
or you can make it more concise as follows:
public boolean equals(Object oo) {
if(oo instanceof Hashvalue && this.x == ((HashValue) oo).x)
return true;
return false;
}
HashValue and Hashvalue are two different identifiers
if(oo instanceof HashValue)
works because your class-name is HashValue
not Hashvalue
EDIT :
Your code doesn't work because hh
isn't in scope when you are using it.
This works:
/* A program to check hashcode values for object
@Author Myth17
*/
class HashValue
{
int x;
public boolean equals(Object oo)
{
HashValue hh=new HashValue();
if(oo instanceof HashValue)
hh = (HashValue)oo;
if(this.x==hh.x)
return true;
else
return false;
}
HashValue()
{
x=11;
}
}
class Hashing
{
public static void main(String args[])
{
HashValue hv=new HashValue();
HashValue hv2=new HashValue();
System.out.println(hv.hashCode());
System.out.println(hv2.hashCode());
if(hv.equals(hv2))
System.out.println("EQUAL");
else
System.out.println("NOT EQUAL");
}
}
int x;
public static void main(String args[]){
E a = new E();
System.out.println(a.hashcode());
E b = new E();
System.out.println(b.hashcode());
}
public int hashcode(){
return x*17;
}
As others have already pointed out it the methods "equals" and the "hashCode" serve different purposes.
From the specification of hashCode method in Objectone can infer that:
Your code (taking into consideration the change tgamblin has proposed) satisfies criteria (a) hence you get the output as "EQUALS".
But is a good practice to follow (b) as this results in better performance when instance of the class are used as hashtable keys. When unequal objects return the same hashCode and if such a class is used as hashtable key, then every object hashes to the same bucket, and hashtable would degenerate to a linkedlist leading to reduced performance.
Equality is only determined by method equals(). And method hashCode() is used in other situations, like by Map or Set. It is somewhat like a pre-condition or hint before actually calling equals (for efficiency). So it is assumed that if 2 objects are equal (that is, equals() returns true), then their hashCodes() must return the same value.
So in your code, 2 objects are equal, as long as your overriden equals() returns true, no matter what hashCode() does. hashCode() is not called at all when comparing for equality.
This question has more in-depth information regarding to the relationship between equals() and hashCode().
First, in that line, you need to change Hashvalue
to HashValue
, since your class is actually called HashValue
.
Then, uncommenting the line gives you this:
public boolean equals(Object oo) {
if(oo instanceof HashValue)
HashValue hh = (HashValue)oo;
if (this.x==hh.x) {
return true;
} else {
return false;
}
}
There are a few things wrong with this:
This doesn't compile because hh
isn't in scope when you end up using it.
The first if statement should either make sure that the function doesn't run at all when you compare two things that aren't HashValues (i.e. throw an exception), or it should return false
because HashValues are never equal to other types of objects. I generally prefer returning false
to throwing an exception.
The second if statement is redundant, because you're just returning what the condition evaluates to.
Rework your method like this:
public boolean equals(Object oo) {
if(!(oo instanceof Hashvalue)) {
return false;
}
HashValue hh = (HashValue)oo;
return (this.x == hh.x);
}
This isn't quite right, either. To make sure that all equal objects have the same hash code, you have to override hashCode() in HashValue
, and you must make sure that it lives up to the guarantee. Here, you could just add this:
// inside HashValue
int hashCode() {
return x;
}
The implementation is trivial because your object is just a wrapper around an int
. You'll need to think harder about this as your objects get more sophisticated.