How to Compare Two Objects in Java (by Overriding equals)

Here’s a simple class you might use in a Java system:

public class Person
{
    public String Name;
    public String SocialSecurityNumber;
    public String PhoneNumber;
 
    public Person(String name, String socialSecurityNumber, String phoneNumber)
    {
        Name = name;
        SocialSecurityNumber = socialSecurityNumber;
        PhoneNumber = phoneNumber;
    }
}

Now let’s say you had instantiated two objects of this class and that they represent the same person (but that you didn’t know it at the time):

Person person1 = new Person("Bob Smith", "000-00-1234", "801-222-1234");
Person person2 = new Person("Robert Smith", "000-00-1234", "801-222-1234");

Let’s say your Java program had simply pulled their information from a database. And suppose that sometimes the database had duplicates of the same person (would be a bad design idea, but unfortunately a reality in many databases). Then you wanted to determine whether these two individuals were identical to each other.

How would you go about that?

You could look at their names, but in this situation you have two different versions of the same person’s name. You could look at the phone numbers, which here are identical, but two different people can have the same phone number. So the obvious answer is social security number.

One seemingly obvious way to do this would be to compare their social security numbers as in the following example:

boolean areEqual = person1.SocialSecurityNumber.equals(person2.SocialSecurityNumber);

This would give you the answer you want. But…this approach has two main limitations: 1) if you have to implement this logic in multiple places in your code and then you change the criteria by which you decide whether two objects are equal, you have to change your code in many different places; 2) behind the scenes, Java often wants to compare two objects, but it doesn’t know by default how to determine equality, so you miss out on that if you don’t do the following.

The better solution would be to override two methods that have default implementations in the Object class, which is inherited by all non-primitive classes in Java: equals and hashCode.

public class Person
{
    public String Name;
    public String SocialSecurityNumber;
    public String PhoneNumber;
 
    public Person(String name, String socialSecurityNumber, String phoneNumber)
    {
	Name = name;
	SocialSecurityNumber = socialSecurityNumber;
	PhoneNumber = phoneNumber;
    }
 
    @Override
    public boolean equals(Object compareObj)
    {
	if (this == compareObj) // Are they exactly the same instance?
           return true;
 
	if (compareObj == null) // Is the object being compared null?
	    return false;
 
	if (!(compareObj instanceof Person)) // Is the object being compared also a Person?
	    return false;
 
	Person comparePerson = (Person)compareObj; // Convert the object to a Person
 
	return this.SocialSecurityNumber.equals(comparePerson.SocialSecurityNumber); // Are they equal?
    }
 
    @Override
    public int hashCode()
    {
	int primeNumber = 31;
	return primeNumber + this.SocialSecurityNumber.hashCode();
    }
}

The equals method allows you to compare like this:

bool areEqual = person1.equals(person2);

Going back to the previous code, in the equals method I am first checking for obvious answers to the question of whether they are equal. If none of those answer the question, then I will look at the actual object being compared (person2 in this case) as well as the current object (person1). It is using social security number to determine whether they are equal. Note that in this line I am using the equals method built into the String class. Also note that the hashCode method is also being overridden. This value is used behind the scenes in Java, and you want it to be unique to that particular object for performance improvements; in this case I am using a prime number (31) plus the hash code value for the social security number.

Now the Java framework can take advantage of this. So, for example, if you put a bunch of Person objects in an ArrayList and wanted to see if an identical person was already in it or wanted to find all the unique objects in it, this would be easy.

Let’s say you wanted to consider two Persons equivalent only if they had the same social security number and the same name. You could change the last line of equals to this:

return this.SocialSecurityNumber.equals(comparePerson.SocialSecurityNumber) &&
    this.Name.equals(comparePerson.Name);

and hashCode to something like this:

@Override
public int hashCode()
{
    int primeNumber = 31;
    return primeNumber + this.SocialSecurityNumber.hashCode() + this.Name.hashCode();
}

Notes:

  • The use of instanceof is explained here
  • Most Java IDEs can implement default code for overriding equals and hashCode
  • Be aware that comparing two objects with == is usually not the same as comparing using the equals method. Except with primitive types, the == operator determines whether two objects are the exact same instance whereas the equals method determines whether two distinct instances are equivalent.

5 Responses to “How to Compare Two Objects in Java (by Overriding equals)”

  1. Very Useful at foundation level

  2. If both objects are null then the objects are indeed equal. Yet your overridden method would return false.

  3. Matt, I see what you’re saying. But the thing is that the equals method could never be called on a null object. So say you have a null Person object. If you tried to ask whether that object was equal to another object, you would get a null pointer exception. In other words, it wouldn’t even enter this method. You’d have to check for them both to be null outside the Person class functionality.

  4. if i want to compare to objects (employee) to see if they have the same name how can i compare it to all the objects (employees) i already have.

  5. Chad. Sorry for my late reply. Can you give me a little more detail on what you’re trying to do? Thanks.

Leave a Reply