1️⃣ Why Is This Implementation Wrong?
❌ Incorrect equals()
Implementation
class MyClass {
public boolean equals(MyClass that) { // ❌ Wrong! Does not override Object.equals()
return this == that;
}
}
📌 Problems:
- Does Not Override
Object.equals(Object)
- Java does not recognize this as an override because the method signature must be
equals(Object that)
. - It is a separate method, not an actual override.
- Java does not recognize this as an override because the method signature must be
- Breaks Polymorphism
- If
MyClass
is used in collections likeHashSet
, Java will callObject.equals()
, not this custom method.
- If
- Only Checks References (
==
)- This makes
equals()
useless because==
already does this. - The whole point of overriding
equals()
is to compare content, not memory addresses.
- This makes
2️⃣ How Java’s equals()
Works
📜 Correct equals(Object)
Signature
The correct method signature for overriding equals()
in Java:
@Override
public boolean equals(Object obj) { ... }
- Java calls
equals(Object)
, notequals(MyClass)
. - Collections (
HashSet
,HashMap
) and built-in methods (contains()
,remove()
) expectequals(Object)
, notequals(MyClass)
.
3️⃣ How This Fails in a HashSet
❌ Wrong Implementation That Breaks HashSet
import java.util.HashSet;
import java.util.Set;
class MyClass {
int value;
public MyClass(int value) {
this.value = value;
}
public boolean equals(MyClass that) { // ❌ Wrong! Does not override Object.equals()
return this == that;
}
}
public class Main {
public static void main(String[] args) {
Set<MyClass> set = new HashSet<>();
MyClass obj1 = new MyClass(42);
MyClass obj2 = new MyClass(42);
set.add(obj1);
System.out.println(set.contains(obj2)); // ❌ false (Expected: true)
}
}
📌 What Went Wrong?
contains(obj2)
checksObject.equals()
, but sinceequals(MyClass)
is not an override, it callsObject.equals()
, which defaults to==
.- Since
obj1 != obj2
, it fails to find the object.
4️⃣ Correct Way to Override equals()
✅ Fixed Version: Correctly Overriding equals(Object)
import java.util.Objects;
class MyClass {
int value;
public MyClass(int value) {
this.value = value;
}
@Override
public boolean equals(Object obj) { // ✅ Correct: Overrides Object.equals()
if (this == obj) return true; // Check reference equality
if (obj == null || getClass() != obj.getClass()) return false; // Check class
MyClass myClass = (MyClass) obj;
return this.value == myClass.value; // Compare content
}
@Override
public int hashCode() {
return Objects.hash(value); // ✅ Ensures compatibility with HashSet
}
}
public class Main {
public static void main(String[] args) {
Set<MyClass> set = new HashSet<>();
MyClass obj1 = new MyClass(42);
MyClass obj2 = new MyClass(42);
set.add(obj1);
System.out.println(set.contains(obj2)); // ✅ true (Now works correctly)
}
}
📌 Now equals()
works properly:
equals()
compares content (value
), not references.contains(obj2)
correctly finds the object in theHashSet
.
📌 Summary: Why equals(MyClass that)
Is Wrong
Issue | Why It Fails |
---|---|
Does Not Override Object.equals(Object) | Java calls equals(Object) , but equals(MyClass) is a separate method. |
Breaks Polymorphism | Collections like HashSet and HashMap rely on Object.equals(Object) , so they won’t recognize this method. |
Only Checks References (== ) | This makes equals() redundant—== already does this. |
✅ Best Practices
✔ Always override equals(Object)
with the correct signature.
✔ Use @Override
to ensure proper overriding.
✔ Compare meaningful fields instead of using ==
.
✔ Override hashCode()
whenever you override equals()
.
By following these rules, your Java objects will work correctly and efficiently in collections! 🚀