Reputation: 27
I know this is asked a lot, and I don't know if I quite understand hash codes, but it's supposed to be the address and so how do I fix my particular example? If my understanding is correct, I have doubles in my class, but I can't add them to the hash code, because of
possible loss of precision
found : double
required: int
return this.area();
Here is my Shape
class:
abstract class Shape implements Comparable<Shape>
{
abstract double area();
public int compareTo(Shape sh){
return Double.compare(this.area(),sh.area());
}
public int hashCode() {
return this.area();
}
public boolean equals(Shape sh) {
if ( sh instanceof Shape && this.area()==sh.area() ) {
return true;
} else {
return false ;
}
}
}
Is area()
the only value I need to worry about in hashCode()?
Upvotes: 1
Views: 3173
Reputation: 795
You could do:
public int hashCode() {
return Double.valueOf(this.area()).hashCode();
}
-- Edition: corrected valueOf method name. Thank you @user4254704.
Upvotes: 0
Reputation: 393856
You can use the example of hashCode in Double class :
public int hashCode() {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
This would avoid the loss of precision caused by simply casting the double to int.
If the area is the only property that determines the hashCode, you can use the exact same code, replacing value
with area
.
However, I'm not sure area
is a good candidate for hashCode calculation, since it is itself calculated from properties of the sub-classes of Shape. You should probably implement hashCode in each sub-class of Shape based on the specific properties of that sub-class.
Upvotes: 3
Reputation: 77187
Don't just add the numbers together to produce a hash code; that's very likely to get duplicate hash codes for unequal objects close together. Instead, I recommend using either the Objects.hash
method from the standard Java API or the more expressive and efficient HashCodeBuilder
from Apache Commons-Lang. You should include in the hashCode
calculation exactly the same fields that you use to determine equals
.
Of course, as @khelwood pointed out, you very likely don't want to implement equals
and hashCode
on this abstract object, since a 1x4 rectangle and a 2x2 rectangle probably aren't equal. Instead, you can re-declare those methods as abstract
on Shape
to force subclasses to implement them:
public abstract class Shape {
@Override
public abstract int hashCode();
}
Upvotes: 1