Search code examples
javahashhashcode

hashCode() method


I need some help in better understanding hashCode() method in a theoretical way. I´ve read (emphasis mine):

When hashCode() is called on two separate objects (which are equal according to the equals() method) it returns the same hash code value. However, if it is called on two unequal objects, it will not necessarily return different integer values.

Where can said exceptions occur?


Solution

  • Suppose you have a class with two String fields, and that its hashcode is calculated by summing the hashcodes of those two fields. Further suppose you have an equals that simply checks whether the class fields values are equal.

    class Test {
        String a;
        String b;
    
        public Test
        
        @Override
        public int hashCode() {
            return a.hashCode() + b.hashCode();
        }
    
    
        @Override
        public boolean equals(Object o) { // simplified
             Test other = (Test)o;
             return a.equals(other.a) && b.equals(other.b);
        }
    }
    

    Let's see if non-equal instances can have the same hashcode

    Test t1 = new Test("hello", "world");
    Test t2 = new Test("world", "hello");
    
    System.out.println(t1.equals(t2));                  // false
    System.out.println(t1.hashCode() == t2.hashCode()); // true
    

    Are we still respecting hashCode's contract?

    Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

    Well, yes, since it only depends on a and b and we're using their hashCode method which we can assume respects the 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.

    It does

    Test t1 = new Test("hello", "world");
    Test t2 = new Test("hello", "world");
    
    System.out.println(t1.equals(t2));                  // true
    System.out.println(t1.hashCode() == t2.hashCode()); // true
    

    It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

    That's what we were trying to demonstrate in the first place. It's not a requirement.