Eugenio Cuevas
Eugenio Cuevas

Reputation: 11078

Hash code for a rational number

I have implemented a class to model rational numbers in java, it has two integers to model numerator and denominator. I am required to override the hashcode method of Object, so the same numbers have the same hash code.

I have defined my equals() method like this:

public boolean equals(Object obj) {
    Racional r = null;
    if (obj instanceof Racional) {
        r = (Racional) obj;
    } else {
        return false;
    }
    return r.getDenominador() * this.numerador == r.getNumerador() * this.denominador;
}

Regarding this:

Would returning numerator * denominator be a good approach?

Should equivalent rational numbers (like 1/4 and 2/8) return the same hashcode?

Upvotes: 1

Views: 1878

Answers (3)

NPE
NPE

Reputation: 500873

Should equivalent rational numbers (like 1/4 and 2/8) return the same hashcode?

Since your equals() method returns true for 1/4 and 2/8, the two numbers must have the same hash code.

One way to achieve this is by simplifying the fraction (for example, at construction time). This can be done by dividing both the numerator and the denominator by their GCD. Once you do this, any reasonable hashCode() function would do the job.

Upvotes: 2

Jeffrey
Jeffrey

Reputation: 44808

It all depends on how you implemented your equals method. If obj1.equals(obj2) is true, obj1.hashCode() == obj2.hashCode() should also be true. I would probably just use new Double((double) numerator / denominator).hashCode() for my hash, but your requirements might not allow that.

/edit
Using numerator * denominator for your hash would be an invalid approach given your equals method. Using your example of 1/4 and 2/8, 1/4.equals(2/8) would return true, but 1/4.hashCode() == 2/8.hashCode() would evaluate to 4 == 16, and return false.

Upvotes: 4

peter.murray.rust
peter.murray.rust

Reputation: 38073

Suggest something like:

37*numerator + 13* denominator

for the hashcode, where these are primes.

And I would regard 1/4 and 2/8 as different unless you have an aggressive normalization policy. But this is up to you. Make sure you document the behaviour well.

UPDATE: You need to decide what equality means. I would normalize first and then write:

return this.numerator == r.numerator && this.denominator == r.denominator

Upvotes: 0

Related Questions