🚀 Can Different Objects (ref0 != ref1
) Have ref0.equals(ref1) == true
?
Yes! Different objects (with different memory addresses) can still be considered equal if equals()
is overridden to compare their contents rather than their references.
1️⃣ Default Behavior of equals()
in Object
By default, equals()
in Object
behaves like ==
, meaning:
public boolean equals(Object obj) {
return (this == obj);
}
- If
equals()
is not overridden, two references must point to the same object forequals()
to returntrue
. - Different objects (
ref0 != ref1
) will returnfalse
by default.
❌ Example: Default equals()
in Object
(Comparing Memory References)
class Person {
String name;
public Person(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
System.out.println(p1 == p2); // ❌ false (Different memory addresses)
System.out.println(p1.equals(p2)); // ❌ false (Default equals() is same as ==)
}
}
📌 Why does equals()
return false
here?
- Since
Person
does not overrideequals()
, it behaves like==
(compares memory references).
2️⃣ Overriding equals()
to Compare Object Contents
To allow different objects to be considered equal, we override equals()
to compare field values instead of memory addresses.
✅ Example: Overriding equals()
for Logical Equality
import java.util.Objects;
class Person {
String name;
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Reflexivity: same reference → true
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name); // Compare contents
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Alice"); // Different object, same content
System.out.println(p1 == p2); // ❌ false (Different objects in memory)
System.out.println(p1.equals(p2)); // ✅ true (Same name, so equals() is true)
}
}
📌 Now equals()
returns true
even though p1
and p2
are different objects!
p1 != p2
(different memory locations).p1.equals(p2) == true
because we comparename
, not references.
3️⃣ Common Cases Where equals()
Returns true
for Different Objects
✅ String
Java’s String
class overrides equals()
to compare characters, not memory references.
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // ❌ false (Different objects)
System.out.println(s1.equals(s2)); // ✅ true (Same character sequence)
📌 Why?
==
compares memory (false).equals()
compares content (true).
✅ Wrapper Classes (Integer
, Double
, etc.)
Java’s wrapper classes (Integer
, Double
, etc.) override equals()
to compare values.
Integer i1 = new Integer(42);
Integer i2 = new Integer(42);
System.out.println(i1 == i2); // ❌ false (Different objects)
System.out.println(i1.equals(i2)); // ✅ true (Same value)
📌 Why?
Integer
overridesequals()
to compare values, not references.
✅ Custom Classes with Overridden equals()
Example with Point class:
class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point) obj;
return this.x == point.x && this.y == point.y;
}
}
public class Main {
public static void main(String[] args) {
Point p1 = new Point(3, 4);
Point p2 = new Point(3, 4);
System.out.println(p1 == p2); // ❌ false (Different memory locations)
System.out.println(p1.equals(p2)); // ✅ true (Same coordinates)
}
}
📌 Summary: When ref0.equals(ref1) == true
Even If ref0 != ref1
Case | ref0 != ref1 | ref0.equals(ref1) |
---|---|---|
Default Object.equals() | ✅ Yes (Different objects) | ❌ false (Default behavior uses == ) |
Overridden equals() in Custom Classes | ✅ Yes | ✅ true (If content is the same) |
String ("hello" ) | ✅ Yes | ✅ true (Compares characters) |
Integer (new Integer(42) ) | ✅ Yes | ✅ true (Compares values) |
✅ Key Takeaways
✔ If equals()
is not overridden, it behaves like ==
(compares references).
✔ If equals()
is overridden, it can return true
for different objects if their contents match.
✔ Java’s built-in classes like String
and Integer
already override equals()
.
✔ Custom classes should override equals()
when logical equality matters.
By following these principles, your Java objects will behave correctly and efficiently in collections like HashSet
and HashMap
! 🚀