Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Things to keep in mind while overriding hashCode

Tags:

java

public class Person {
    private String name, comment;
    private int age;

    public Person(String n, int a, String c) {
        name = n;
        age = a;
        comment = c;
    }

    public boolean equals(Object o) {
        if (!(o instanceof Person))
            return false;
        Person p = (Person) o;
        return age == p.age && name.equals(p.name);
    }
}

What is the appropriate definition of the hashCode method in class Person?

A. return super.hashCode();
B. return name.hashCode() + age * 7;
C. return name.hashCode() + comment.hashCode() / 2;
D. return name.hashCode() + comment.hashCode() / 2 - age * 3;

The answer is B.

Can someone explain, why C and D are wrong?

like image 989
Abhishek Singh Avatar asked Mar 29 '15 15:03

Abhishek Singh


3 Answers

For A, C and D, hashCode() might return a different result for 2 instances of Person whose equals() method returns true, i.e. two Persons that are equal might return different hash codes.

This clearly violates Object.hashCode()'s contract:

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.

For C and D, if two Persons had the same age and name but different comment, equals() would return true, while hashCode() would produce different values.

For A, as Person implicitly descends from the Object class (i.e. it doesn't extend from any explicit superclass), the result of super.hashCode() would be equal only when invoked on the same instance. According to Object.hashCode() docs:

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.)

So, if you had two different instances of the Person class, both with the same name, age and comment, equals() would return true, while hashCode() would return different values, violating hashCode()'s contract.

In practice, this means that the Person class could not be the key of any Map.

like image 67
fps Avatar answered Oct 11 '22 05:10

fps


The equals method says that objects are equal when they have the same name and age. The comments don't affect equality here.

The contract of equals and hashCode requires that 2 equal objects have the same hashCode.

C and D can violate this rule because objects with the same name and age, but different comments result in different hashCodes.

like image 26
fgb Avatar answered Oct 11 '22 03:10

fgb


From cursory reading. It seems B is the better one because of the equal() method take account of those two variables (which is name and age).

like image 23
kucing_terbang Avatar answered Oct 11 '22 03:10

kucing_terbang