override equals in Java

equals() (javadoc) must define an equality relation (it must be reflexivesymmetric, and transitive). In addition, it must be consistent (if the objects are not modified, then it must keep returning the same value). Furthermore, o.equals(null) must always return false.

hashCode() (javadoc) must also be consistent (if the object is not modified in terms of equals(), it must keep returning the same value).

The relation between the two methods is:

Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().

Steps to Override equals method in Java

Here is my approach for overriding equals method in Java. This is based on standard approach most of Java programmer follows while writing equals method in Java.
 
1) Do this check -- if yes then return true.
2) Do null check -- if yes then return false.
3) Do the instanceof check,  if instanceof return false than return false from equals in Java , after some research I found that instead of instanceof we can use getClass() method for type identification because instanceof check returns true for subclass also, so its not strictly equals comparison until required by business logic. Butinstanceof check is fine if your class is immutable and no one is going to sub class it. For example we can replace instanceof check by below code
 
if((obj == null) || (obj.getClass() != this.getClass()))
        return false;
 
4) Type cast the object; note the sequence instanceof check must be prior to casting object.
 
5) Compare individual attribute starting with numeric attribute because comparing numeric attribute is fast and use short circuit operator for combining checks.  If first field does not match, don't try to match rest of attribute and return false. It’s also worth to remember doing null check on individual attribute before calling equals() method on them recursively to avoid NullPointerException during equals check in Java.

In practice:

If you override one, then you should override the other.

Use the same set of fields that you use to compute equals() to compute hashCode().

Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Langlibrary. An example:

 1 public class Person {
 2     private String name;
 3     private int age;
 4     // ...
 5 
 6     public int hashCode() {
 7         return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
 8             // if deriving: appendSuper(super.hashCode()).
 9             append(name).
10             append(age).
11             toHashCode();
12     }
13 
14     public boolean equals(Object obj) {
15         if (obj == null)
16             return false;
17         if (obj == this)
18             return true;
19         if (!(obj instanceof Person))
20             return false;
21 
22         Person rhs = (Person) obj;
23         return new EqualsBuilder().
24             // if deriving: appendSuper(super.equals(obj)).
25             append(name, rhs.name).
26             append(age, rhs.age).
27             isEquals();
28     }
29 }

OR

 1 /** 
 2  * Person class with equals and hashcode implementation in Java
 3  * @author Javin Paul
 4  */
 5 public class Person {
 6     private int id;
 7     private String firstName;
 8     private String lastName;
 9 
10     public int getId() { return id; }
11     public void setId(int id) { this.id = id;}
12 
13     public String getFirstName() { return firstName; }
14     public void setFirstName(String firstName) { this.firstName = firstName; }
15 
16     public String getLastName() { return lastName; }
17     public void setLastName(String lastName) { this.lastName = lastName; }
18 
19     @Override
20     public boolean equals(Object obj) {
21         if (obj == this) {
22             return true;
23         }
24         if (obj == null || obj.getClass() != this.getClass()) {
25             return false;
26         }
27 
28         Person guest = (Person) obj;
29         return id == guest.id
30                 && (firstName == guest.firstName 
31                      || (firstName != null && firstName.equals(guest.getFirstName())))
32                 && (lastName == guest.lastName 
33                      || (lastName != null && lastName .equals(guest.getLastName())));
34     }
35     
36     @Override
37     public int hashCode() {
38         final int prime = 31;
39         int result = 1;
40         result = prime * result
41                 + ((firstName == null) ? 0 : firstName.hashCode());
42         result = prime * result + id;
43         result = prime * result
44                 + ((lastName == null) ? 0 : lastName.hashCode());
45         return result;
46     }
47     
48 }

 

Also remember:

When using a hash-based Collection or Map such as HashSetLinkedHashSetHashMapHashtable, orWeakHashMap, make sure that the hashCode() of the key objects that you put into the collection never changes while the object is in the collection. The bulletproof way to ensure this is to make your keys immutable, which has also other benefits.

posted on 2013-12-08 03:07  Step-BY-Step  阅读(968)  评论(0编辑  收藏  举报

导航