Java equals method - Tutorial

All classes in Java are child classes of the Object class that you can find in java.lang package in rt.jar. If you open the Object class, you will see that it has many methods and one of the very important ones that we are going to discuss in this tutorial is the equals(Object obj) method.

Let's open the java.lang.Object class and look at the default implementation of the equals method.

Default implementation of equals method in Object class:
public boolean equals(Object obj) {
        return (this == obj);
    }

As you can see, the default implementation uses double equals-to == comparison of the current object and the object passed on to the equals method. == does the address comparison

Example 1: Without overriding equals method

public class EqualsExampleJava {
    
    public static void main(String[] args) {
        Employee employee1 = new Employee(1, "Sam");
        Employee employee2 = employee1; //same reference
        Employee employeeDup = new Employee(1, "Sam");

        System.out.println("employee1 == employee2 => " + (employee1 == employee2));
        System.out.println("employee1.equals(employee2) => " + employee1.equals(employee2));

        System.out.println("employee1 == employeeDup => " + (employee1 == employeeDup));
        System.out.println("employee1.equals(employeeDup) => " + employee1.equals(employeeDup));
    }
}

class Employee {
    int employeeId;
    String employeeName;

    Employee(int employeeId, String employeeName) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
    }
}
Output:

employee1 == employee2 => true
employee1.equals(employee2) => true

employee1 == employeeDup => false
employee1.equals(employeeDup) => false

You will get the same results when comparing two objects using == and equals methods if you do not override the equals method.

✏️ Always compare two objects (created using the new keyword) using the equals(Object obj) method and by overriding it in your class.

In our example, we say that two employees are the same if their name and id are the same,

Example 2: Overriding equals method

class Employee {
    int employeeId;
    String employeeName;

    Employee(int employeeId, String employeeName) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
    }

    @Override
    public boolean equals(Object obj) {
        //If object is null then they are not same
        if(obj == null) return false;

        //If object is have the same reference they are same
        if(obj == this) return true;

        //Check if the object is an instance of Employee
        if(!(obj instanceof Employee)) return false;

        Employee employee = (Employee) obj;

        return this.employeeId == employee.employeeId &&
                 this.employeeName.equals(employee.employeeName);
    }
}

public class EqualsExampleJava {
    public static void main(String[] args) {
        Employee employee1 = new Employee(1, "Sam");
        Employee employee2 = employee1; //same reference
        Employee employeeDup = new Employee(1, "Sam");

        System.out.println("employee1 == employee2 => " + (employee1 == employee2));
        System.out.println("employee1.equals(employee2) => " + employee1.equals(employee2));

        System.out.println("employee1 == employeeDup => " + (employee1 == employeeDup));
        System.out.println("employee1.equals(employeeDup) => " + employee1.equals(employeeDup));
    }
}
Output:

employee1 == employee2 => true
employee1.equals(employee2) => true

employee1 == employeeDup => false
employee1.equals(employeeDup) => true

Example 3: Overriding equals and hashCode methods

import java.util.Objects;

class Employee {
    int employeeId;
    String employeeName;

    Employee(int employeeId, String employeeName) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Employee employee = (Employee) obj;
        return employeeId == employee.employeeId &&
                Objects.equals(employeeName, employee.employeeName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(employeeId, employeeName);
    }
}

public class EqualsHashCodeExample {
    public static void main(String[] args) {
        Employee emp1 = new Employee(1, "John");
        Employee emp2 = new Employee(1, "John");
        Employee emp3 = new Employee(2, "Jane");

        System.out.println("emp1.equals(emp2): " + emp1.equals(emp2));
        System.out.println("emp1.equals(emp3): " + emp1.equals(emp3));
        System.out.println("emp1.hashCode() == emp2.hashCode(): " + (emp1.hashCode() == emp2.hashCode()));
        System.out.println("emp1.hashCode() == emp3.hashCode(): " + (emp1.hashCode() == emp3.hashCode()));
    }
}
Output:

emp1.equals(emp2): true
emp1.equals(emp3): false
emp1.hashCode() == emp2.hashCode(): true
emp1.hashCode() == emp3.hashCode(): false



Frequently Asked Questions (FAQ)

  • Q: What is the equals() method in Java?

    A: The equals() method in Java is used to compare two objects for equality. By default, it compares object references, but it can be overridden to compare object contents.

  • Q: Why should I override the equals() method?

    A: You should override the equals() method to provide a meaningful way to compare objects based on their content rather than their memory addresses.

  • Q: What is the difference between == and equals() in Java?

    A: The == operator compares object references (memory addresses), while equals() can be overridden to compare object contents.

  • Q: What is the relationship between equals() and hashCode()?

    A: If you override equals(), you should also override hashCode(). Objects that are equal according to equals() must return the same hashCode().

  • Q: How do I properly implement the equals() method?

    A: To properly implement equals(), check for null, same reference, correct type, and then compare relevant fields. Use Objects.equals() for non-primitive fields to handle null values.

  • Q: What are the common pitfalls when overriding equals()?

    A: Common pitfalls include forgetting to override hashCode(), not maintaining symmetry, transitivity, or consistency, and using the wrong parameter type (Object instead of the specific class).

  • Q: How does equals() affect collections like HashSet or HashMap?

    A: These collections use both equals() and hashCode() to determine object uniqueness and position. Incorrect implementations can lead to unexpected behavior in these collections.

  • Q: Can I use @Override annotation with equals() method?

    A: Yes, it's recommended to use @Override annotation when overriding equals(). This helps catch errors if the method signature is incorrect.

Comments & Discussion

Facing issues? Have questions? Post them here! We're happy to help!