learning_user7
learning_user7

Reputation: 27

Overriding HashCode() in Java with double values

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

Answers (3)

ArturoTena
ArturoTena

Reputation: 795

You could do:

public int hashCode() {
  return Double.valueOf(this.area()).hashCode();
}

-- Edition: corrected valueOf method name. Thank you @user4254704.

Upvotes: 0

Eran
Eran

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

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

Related Questions