Learntofish's Blog

A blog about math, physics and computer science

Override equals and hashCode in Java

Posted by Ed on August 26, 2018

Introduction

If you want to compare objects of your class in Java you have to define how they are compared. This is done by overriding the equals() and hashCode() methods. There are a few things to consider for these methods, and you can read about it here, e.g.

  • 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.
  • The equals(Object) method must be reflexive, symmetric and transitive.

Example

Let’s consider the following class:


public class Student {
private String name;
private int id;

public Student(String name, int id) {
this.name = name;
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
}

In Eclipse we can automatically generate the equals() and hashCode() method. For this click on your file,

  • right click on it,
  • choose Source -> Generate hashCode() and equals()
  • Check the boxes at the top to select the attributes that are accounted for, i.e. name and id.
  • Check the box “Use instanceof to compare types”.

The result is the following:


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
Student other = (Student) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

(Apologies for the missing code format above, especially the ones indicate the proper if-else structure. I can’t figure out how to preserve the code formatting when copying it from the Eclipse editor. Please do try out the steps above in the editor, thank you for your understanding!)

We first check three things:

  1. In line 12 we check if the two objects that we are comparing are the same instance, i.e. we are checking if the two references are pointing to the same memory address.
  2. In line 14 we check if the object that we are comparing against is null.
  3. In line 16 we check if the object obj that we are comparing against is of the same type, or if obj has a type of a class that inherits from Student.

Finally, from line 18 we compare the attributes.

Different equals() method

Note that it is conceivable that the ID of a student alone determines whether two students are equal. For an example, I recommend this excellent article by Hussein Terek.

getClass() vs instanceof

In some examples such as here and here you will see the use of getClass() instead of instanceof:


if (this.getClass() != obj.getClass()) {

return false;

}

 

The usage depends on what you are trying to compare. If you want two objects to be different if they are of different types, then use getClass(). However, if you want to allow comparing an object of type A with an object of type B, where B extends A, then you have to use instanceof.  See also this StackOverflow discussion.

Further readings and references

Leave a comment