In Java, equals()
method is used to compare the equivalence between two objects. hashCode()
method is used to generate the object's hash code which is used to properly distribute entries across hash table based collections such as HashMap or HashSet
By default, both of them are defined in the Object
class and inherited by all Java classes. However, you should consider to override them on your classes to make them useful in practice
The equals()
method of Object
class
The equals()
method of Object
class is defined as below
public boolean equals(Object obj) {
return (this == obj);
}
It returns true
when the calling object this
and the parameter obj
point to the same memory address
The default equals()
method problem
In practice, besides comparing memory addresses, you also need the equals()
method comparing your objects based on their internal fields
In the following example, book1.equals(book2)
should return true but false as BookWithoutEquals
's equals
method is derived from Object
so it's only comparing memory addresses of book1
and book2
which always returns false
@Test
public void givenNonEqualsImplement_whenCompareObjects_thenReturnsFalse() {
BookWithoutEquals book1 = new BookWithoutEquals("A");
BookWithoutEquals book2 = new BookWithoutEquals("A");
assertThat(book1.equals(book2)).isFalse();
}
How to implement a custom equals()
method
The implementation usually has 3 parts
- Compares memory addresses of the owner and the parameter object
if (this == o) return true;
- Checks the nullability of the parameter and compares the class type of the owner and the parameter
if (o == null || getClass() != o.getClass()) return false;
- Compares object fields by using Java 7+
Objects.equals
return Objects.equals(title, that.title) &&
Objects.equals(pages, that.pages);
The following gives you implementation example
book1.equals(book2)
now returns true as expected
@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 generates an object's hash code value. It is used to properly distribute entries across hash table based collections such as HashMap and HashSet
Learn more about hash table data structure
Lack of equals()
and hashCode()
implementation in your classes can cause troubles when they are stored inside a HashMap or HashSet. Let's take a look at this example
@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 successful as containsKey
method of HashMap works based on BookWithEquals's hashCode()
and equals()
but only equals()
method is overridden
Learn more about Objects comparing in HashMap
How to implement a custom hashCode()
method
Since Java 7, you can delegate the hash code generation to Object.hash
function
return Objects.hash(title, pages);
The following gives you an implementation example
bookMap.containsKey(new BookWithEqualsAndHashCode("A", 1))
now returns true as expected
@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();
}
General contract of equals and hashCode
hashCode()
method must consistently return the same integer during an execution of a Java applicationIf two objects are equals according to the
equals(Object)
method, then their'shashCode()
method must produce the same integer result
Generate equals()
and hashCode()
implementation
You can use the following options to generate equals()
and hashCode()
implementation on your classes
Lombok
@EqualsAndHashCode
or@Data
IDE such as IntelliJ or Eclipse
Conclusion
In this tutorial, we learned about equals()
and hashCode()
methods in Java, and how to override them. You can find below all the defined test cases