Question
How do default implementations of .equals() and .hashCode() behave in custom Java classes?
public class MyObj { /* attributes and methods */ }
Answer
In Java, every class inherits from the Object class, which provides default implementations of the .equals() and .hashCode() methods. Understanding how these methods function is crucial for managing object comparison and uniquely identifying objects in collections.
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyObj myObj = (MyObj) obj;
// Compare relevant attributes
return this.attribute1.equals(myObj.attribute1);
}
@Override
public int hashCode() {
return Objects.hash(attribute1);
}
Causes
- The default .equals() method compares the memory addresses of the two object references.
- The default .hashCode() method returns a hash code value based on the internal memory address of the object.
Solutions
- Override .equals() to implement logical equality based on the attributes that define your class's identity.
- Override .hashCode() to ensure consistent hash codes when .equals() is overridden, maintaining the contract between the two methods.
Common Mistakes
Mistake: Not overriding both .equals() and .hashCode() when defining equality of class instances.
Solution: Always override both methods to ensure the contract between them is maintained.
Mistake: Using mutable fields in the implementation of .hashCode() method, which can lead to inconsistent results.
Solution: Use immutable fields for calculating hash codes to maintain stability.
Helpers
- Java equals method
- Java hashCode method
- Java Object class
- Override equals and hashCode
- Java custom classes