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
ande2
are two different objects stored at different memory locations.==
compares memory addresses, not content. Since they point to different objects,e1 == e2
returnsfalse
.- The default
equals()
method (inherited fromObject
) also checks memory addresses, so it returnsfalse
.
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:
this == obj
→ If both references point to the same object, returntrue
.obj == null || getClass() != obj.getClass()
→ Ensures we are comparing the same type of objects.- Type Casting → Converts
obj
into anEmployee
object. - Content Comparison → Checks if
empId
andname
(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()
andindexOf()
useequals()
to check equality.- Without overriding
equals()
, these methods check memory addresses and returnfalse
. - After overriding, they correctly identify the employee based on
empId
andname
.
Summary
Comparison Type | Checks | Behavior |
---|---|---|
== | Memory address | Returns true only if both references point to the same object |
.equals() (default) | Memory address | Same as == unless overridden |
.equals() (overridden) | Content | Compares 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. 🚀
Leave a Reply