rules for overriding equals

Putting it all together, here’s a recipe for a high-quality equals method:
1. Use the == operator to check if the argument is a reference to this object. If so, return true.
2. Use the instanceof operator to check if the argument is of 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. The collection interfaces Set,
List, Map, and Map.Entry have this property.
3. Cast the argument to the correct type. Because this cast was preceded by
an instanceof test, it is guaranteed to succeed.
4. For each “significant” field in the class, check to see if that field of the argument matches the corresponding field of this object. If all these tests succeed, return true; otherwise, return false. If the type in Step 2 is an interface, you must access the argument’s significant fields via interface methods; if the type is a class, you may be able to access the fields directly, depending on their accessibility. For primitive fields whose type is not float or double, use the == operator for comparisons; for object reference fields, invoke the equals method recursively; for float fields, translate to int values using Float.floatToIntBits and compare the int values using the == operator; for double fields, translate to long values using Double.doubleToLongBits and compare the long values using the == operator. (The special treatment of float and double fields is made necessary by the existence of Float.NaN, -0.0f, and the analogous double constants; see the Float.equals documentation for details.) For array fields, apply these guidelines to each element. Some object reference fields may legitimately contain null. To avoid the possibility of a NullPointerException, use the following idiom to compare such fields: (field == null ? o.field == null : field.equals(o.field)) This alternative may be faster if field and o.field are often identical object references: (field == o.field || (field != null && field.equals(o.field)))
5-When you are finished writing your equals method, ask yourself three questions:
Is it symmetric, is it transitive, and is it consistent? (The other two properties
generally take care of themselves.) If not, figure out why these properties fail to hold,
and modify the method accordingly.
6-Always override hashCode when you override equals
source: Effective Java: Programming Language Guide chapter 3

Example:
public final class PhoneNumber {
private final short areaCode;
private final short exchange;
private final short extension;
public PhoneNumber(int areaCode, int exchange,
int extension) {
rangeCheck(areaCode,999, "area code");
rangeCheck(exchange,
999, "exchange");
rangeCheck(extension, 9999, "extension");
this.areaCode = (short) areaCode;
this.exchange = (short) exchange;
this.extension = (short) extension;
}
private static void rangeCheck(int arg, int max,
String name) {
if (arg < 0 || arg > max)
throw new IllegalArgumentException(name +": " + arg);
}
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false;
PhoneNumber pn = (PhoneNumber)o;
return pn.extension == extension &&
pn.exchange == exchange &&
pn.areaCode == areaCode;
}
// No hashCode method!
}

Suppose you attempt to use this class with a HashMap:
Map m = new HashMap();
m.put(new PhoneNumber(408, 867, 5309), "Jenny");
At this point, you might expect m.get(new PhoneNumber(408, 867, 5309)) to return
"Jenny", but it returns null.
Advertisements

About lorddisk

WebCenter Content, WebCenter Portal, WebCenter Sites,Weblogic, Identity and Access Management (IAM),SSO,OAM,OIM,OAAM,OUD, OPAM,OID, OVD ,Oracle API Gateway ,OBIEE,OEDQ, Oracle ADF, Oracle SOA,J2EE, CackePHP ,PHP,J2SE,J2EE,Spring,Hibernate,JQuery,CSS,Java Script ,Joomla,Drupal,Worpress
This entry was posted in java. Bookmark the permalink.