Object Comparison in Java

Object Comparison in Java

Why Object Comparison Matters

In Java, when comparing objects, we often expect two objects with the same content to be equal. However, due to how object references work, == and .equals() behave differently. Let’s explore this step by step.

Problem: Objects Are Not Equal by Default

Consider the following code snippet:

Employee e1 = new Employee(121, "Raj");
Employee e2 = new Employee(121, "Raj");
System.out.println(e1 == e2);  <em>// false</em>
System.out.println(e1.equals(e2));  <em>// false (before overriding equals)</em>

Explanation:

  • e1 and e2 are two different objects stored at different memory locations.
  • == compares memory addresses, not content. Since they point to different objects, e1 == e2 returns false.
  • The default equals() method (inherited from Object) also checks memory addresses, so it returns false.

Memory Representation:

Heap Memory:
 e1 --> [ Employee@1a2b3c ]
 e2 --> [ Employee@4d5e6f ]

Even though both objects have the same empId and name, Java treats them as different.

Solution: Overriding equals()

To compare object content instead of memory references, we must override equals():

@Override
public boolean equals(Object obj) {
    if (this == obj) return true; <em>// Check if both references are same</em>
    if (obj == null || getClass() != obj.getClass()) return false; <em>// Type check</em>
    Employee employee = (Employee) obj; <em>// Cast to Employee</em>
    return this.empId == employee.empId && this.name.equalsIgnoreCase(employee.name);
}

How It Works:

  1. this == obj → If both references point to the same object, return true.
  2. obj == null || getClass() != obj.getClass() → Ensures we are comparing the same type of objects.
  3. Type Casting → Converts obj into an Employee object.
  4. Content Comparison → Checks if empId and name (ignoring case) are equal.

Updated Comparison:

Employee e1 = new Employee(121, "Raj");
Employee e2 = new Employee(121, "Raj");
System.out.println(e1.equals(e2)); <em>// Now returns true</em>

Object Comparison in Collections

Even after overriding equals()ArrayList methods like contains() and indexOf() rely on it:

List<Employee> list = new ArrayList<>();
list.add(new Employee(121, "E1"));
list.add(new Employee(122, "E2"));
list.add(new Employee(123, "E3"));
list.add(new Employee(124, "E4"));

Employee employee = new Employee(124, "E4");
System.out.println(list.contains(employee)); <em>// true (after overriding equals)</em>
System.out.println(list.indexOf(employee)); <em>// Correct index returned</em>
list.remove(employee);
System.out.println(list); <em>// Employee removed successfully</em>

Why Does This Work?

  • contains() and indexOf() use equals() to check equality.
  • Without overriding equals(), these methods check memory addresses and return false.
  • After overriding, they correctly identify the employee based on empId and name.

Summary

Comparison TypeChecksBehavior
==Memory addressReturns true only if both references point to the same object
.equals() (default)Memory addressSame as == unless overridden
.equals() (overridden)ContentCompares field values
contains()indexOf() (List)Uses .equals()Works correctly when .equals() is overridden

By overriding equals(), we ensure objects are compared based on meaningful data rather than memory locations. 🚀