The equals() and hashCode() methods are defined in the Object class and inherited by all Java classes. However, for more useful, consider to override them on your objects

The equals() method

The equals() method of Object class is defined as below

public boolean equals(Object obj) {  
    return (this == obj);
}
  • It returns true when the calling and the specified obj refer to the same object (same physical memory address) so the following example is always false
@Test
public void givenNonEqualsImplement_whenCompareObjects_thenReturnsFalse() {  
    BookWithoutEquals book1 = new BookWithoutEquals("A");
    BookWithoutEquals book2 = new BookWithoutEquals("A");

    assertThat(book1.equals(book2)).isFalse();
}

BookWithoutEquals is defined as below


  • To make it useful, let add equals() method into the above class. Now the test case returns true when comparing two implemented objects

Objects provides utility methods for operating on objects, available since Java 7

@Test
public void givenEqualsImplement_whenCompareObjects_thenReturnsTrue() {  
    BookWithEquals book1 = new BookWithEquals("A", 1);
    BookWithEquals book2 = new BookWithEquals("A", 1);

    assertThat(book1.equals(book2)).isTrue();
}

The hashCode() method

The hashCode() method returns a hash code value for the object. It provide benefits for objects in hash-based collection like HashMap

@Test
public void givenEqualsImplement_whenCompareInHashMap_thenReturnsTrue() {  
    BookWithEquals bookA = new BookWithEquals("A", 1);
    BookWithEquals bookB = new BookWithEquals("B", 2);
    Map<BookWithEquals, Integer> bookMap = Map.of(bookA, 1, bookB, 2);

    assertThat(bookMap.containsKey(new BookWithEquals("A", 1))).isTrue();
}

The above test case is not success as BookWithEquals only overrides equals(Object) method

@Test
public void givenEqualsAndHashCodeImplement_whenCompareInHashMap_thenReturnsTrue() {  
    BookWithEqualsAndHashCode bookA = new BookWithEqualsAndHashCode("A", 1);
    BookWithEqualsAndHashCode bookB = new BookWithEqualsAndHashCode("B", 2);
    Map<BookWithEqualsAndHashCode, Integer> bookMap = Map.of(bookA, 1, bookB, 2);

    assertThat(bookMap.containsKey(new BookWithEqualsAndHashCode("A", 1))).isTrue();
}

The above test case is success as BookWithEqualsAndHashCode overrides both equals(Object) and hashcode() methods

BookWithEqualsAndHashCode is defined as below


The general contract of hashCode is:

  • Must consistently return the same integer during an execution of a Java application

  • If two object are equals according to the equals(Object) method, then their's hashCode() method must produce the same integer result

Conclusion

In this tutorial, we learned about the Java equals() and hashCode() methods and when we should override them. You can find below all the defined test cases


Notes

  • Map.of(...) is available since Java 9+