Object class have methods like equals() and hashcode(). These methods have their own contracts which have to be fulfilled to override them.
Default implementation of equals() in object class
The default implementation of equals() in Object class is based on the == operator: Two objects are equal if and only if they are the same object. Naturally, most classes should define their own alternative implementation of this important method.
Contract of equals method
Implementing equals() correctly is not straightforward. The equals() method has a contract that says the equality relation must meet these demands: - It must be reflexive. For any reference x, x.equals(x) must return True.
- It must be symmetric. For any two nonnull references x and y, x.equals(y) should return the exact same value as y.equals(x).
- It must be transitive. For any three references x, y, and z, if x.equals(y) and y.equals(z) are True, then x.equals(z) must also return True.
- It should be consistent. For any two references x and y, x.equals(y) should return the same value if called repeatedly (unless, of course, either x or y were changed between the repeated invocations of equals()).
- For any nonnull reference x, x.equals(null) should return False.
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
Steps to be taken when implementing equals()
- Use the == operator to check whether the incoming object is null. Its kind of performance optimization.
public boolean equals(Object incomingObject) { if (incomingObject == null) return false; }
- Use the == operator to check if the argument is a reference to this object. If
so, return true. This is just a performance optimization, but one that
is worth doing if the comparison is potentially expensive.
public boolean equals(Object incomingObject){ if(this==incomingObject) return true; }
- Use the instanceof operator to check if the argument has the correct type.
If not, return false. Typically, the correct type is the class in which the method occurs. Occasionally, it is some interface implemented by this class. Use an interface if the class implements an interface that refines the equals contract to permit comparisons across classes that implement the interface. Collection interfaces such as Set, List, Map, and Map.Entry have this property.public boolean equals(){ if (!(incomingObject instanceof MyClass)) return false; }
if(incomingObject instanceof MyClass) do something;
- Cast the argument to the correct type. Because this cast was preceded by an instanceof test, it is guaranteed to succeed.
public boolean equals(Object incomingObject){ MyClass mc = (MyClass) incomingObject; }
- For each “significant” field in the class, checks if that field of the argument matches the corresponding field of this object. If all these tests succeed, return true; otherwise, return false
-
Writing the complete equals function
Finishing whole steps:
public boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (!(o instanceof MyClass)) return false; MyClass mc = (MyClass) o; return ... // compare members of mc }
- When you are finished writing your equals method, ask yourself three questions: Is it symmetric? Is it transitive? Is it consistent?
Thanks
No comments:
Post a Comment