Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding equals() & hashCode() in sub classes ... considering super fields

Is there a specific rule on how Overriding equals() & hashCode() in sub classes considering super fields ?? knowing that there is many parameters : super fields are private/public , with/without getter ...

For instance, Netbeans generated equals() & hashCode() will not consider the super fields ... and

    new HomoSapiens("M", "80", "1.80", "Cammeron", "VeryHot").equals(     new HomoSapiens("F", "50", "1.50", "Cammeron", "VeryHot")) 

will return true :(

public class Hominidae {      public String  gender;     public String  weight;     public String  height;      public Hominidae(String gender, String weight, String height) {         this.gender = gender;         this.weight = weight;         this.height = height;     }     ...  }  public class HomoSapiens extends Hominidae {     public String name;     public String faceBookNickname;      public HomoSapiens(String gender, String weight, String height,                         String name, String facebookId) {         super(gender, weight, height);         this.name = name;         this.faceBookNickname = facebookId;     }     ...   } 

If you want to see the Netbeans generated equals() & hashCode() :

public class Hominidae {      ...      @Override     public boolean equals(Object obj) {         if (obj == null) {             return false;         }         if (getClass() != obj.getClass()) {             return false;         }         final Hominidae other = (Hominidae) obj;         if ((this.gender == null) ? (other.gender != null) : !this.gender.equals(other.gender)) {             return false;         }         if ((this.weight == null) ? (other.weight != null) : !this.weight.equals(other.weight)) {             return false;         }         if ((this.height == null) ? (other.height != null) : !this.height.equals(other.height)) {             return false;         }         return true;     }      @Override     public int hashCode() {         int hash = 5;         hash = 37 * hash + (this.gender != null ? this.gender.hashCode() : 0);         hash = 37 * hash + (this.weight != null ? this.weight.hashCode() : 0);         hash = 37 * hash + (this.height != null ? this.height.hashCode() : 0);         return hash;     }  }   public class HomoSapiens extends Hominidae {      ...      @Override     public boolean equals(Object obj) {         if (obj == null) {             return false;         }         if (getClass() != obj.getClass()) {             return false;         }         final HomoSapiens other = (HomoSapiens) obj;         if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {             return false;         }         if ((this.faceBookNickname == null) ? (other.faceBookNickname != null) : !this.faceBookNickname.equals(other.faceBookNickname)) {             return false;         }         return true;     }      @Override     public int hashCode() {         int hash = 7;         hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);         hash = 89 * hash + (this.faceBookNickname != null ? this.faceBookNickname.hashCode() : 0);         return hash;     } } 
like image 211
wj. Avatar asked Jan 14 '10 19:01

wj.


People also ask

Can you override equals method?

You can override the equals method on a record, if you want a behavior other than the default. But if you do override equals , be sure to override hashCode for consistent logic, as you would for a conventional Java class.

What is the reason for overriding equals () method?

We can override the equals method in our class to check whether two objects have same data or not.

What are equals () and hashCode () overriding rules?

if a class overrides equals, it must override hashCode. when they are both overridden, equals and hashCode must use the same set of fields. if two objects are equal, then their hashCode values must be equal as well. if the object is immutable, then hashCode is a candidate for caching and lazy initialization.


1 Answers

Children should not examine the private members of their parents

But obviously, all significant fields should be taken into account for equality and hashing.

Fortunately, you you can easily satisfy both rules.

Assuming you're not stuck using the NetBeans-generated equals and hashcode, you can modify Hominidae's equals method to use instanceof comparison rather than class equality, and then use it straightforwardly. Something like this:

     @Override       public boolean equals(Object obj) {           if (obj == null) { return false; }           if (getClass() != obj.getClass()) { return false; }           if (! super.equals(obj)) return false;         else {            // compare subclass fields         } 

Of course, hashcode is easy:

     @Override          public int hashCode() {              int hash = super.hashCode();         hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);              hash = 89 * hash + (this.faceBookNickname != null ? this.faceBookNickname.hashCode() : 0);              return hash;          }      

Seriously, though: what's up with NetBeans not taking superclass fields into account by calling the superclass methods?

like image 94
CPerkins Avatar answered Oct 15 '22 14:10

CPerkins