简体   繁体   中英

Overriding hashcode method for class with lists of objects as fields

Stuck from some time on this point, I have a class(A) with 4 fields ,3 object arraylist and 1 string arraylist. I have overridden equals and hashcode method accordingly,I create multiple objects of class A and add to a hashmap for some logic. But for random objects with same values I am getting a different hash code value and hence when i try hashmap.get(object) randomly fails , Any help is appreciated, Below is the class.

import java.util.ArrayList;
import java.util.List;

import com.makinglifeeasy4u.util.AddressBean;
import com.makinglifeeasy4u.util.EmailBean;
import com.makinglifeeasy4u.util.PhoneBean;

public class ContactsMainBean {

    String contact_id;
    String name;
    private List<PhoneBean> phonelist = new ArrayList<PhoneBean>();
    private List<EmailBean> emaillist = new ArrayList<EmailBean>();
    private List<AddressBean> addressbean = new ArrayList<AddressBean>();
    private List<String> notesList = new ArrayList<String>();

    public String getContact_id() {
        return contact_id;
    }

    public void setContact_id(String contact_id) {
        this.contact_id = contact_id;
    }

    public List<String> getNotesList() {
        return notesList;
    }

    public void setNotesList(List<String> notesList) {

        if (this.notesList != null && this.notesList.size() > 0) {
            this.notesList.addAll(notesList);
        } else {
            this.notesList = notesList;
        }
        // this.notesList = notesList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<PhoneBean> getPhonelist() {
        return phonelist;
    }

    public void setPhonelist(List<PhoneBean> phonelist) {
        if (this.phonelist != null && this.phonelist.size() > 0) {
            this.phonelist.addAll(phonelist);
        } else {
            this.phonelist = phonelist;
        }

    }

    public List<EmailBean> getEmaillist() {

        return emaillist;
    }

    public void setEmaillist(List<EmailBean> emaillist) {
        if (this.emaillist != null && this.emaillist.size() > 0) {
            this.emaillist.addAll(emaillist);
        } else {
            this.emaillist = emaillist;
        }
        // this.emaillist = emaillist;
    }

    public List<AddressBean> getAddressbean() {
        return addressbean;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((addressbean == null) ? 0 : addressbean.hashCode());
        result = prime * result
                + ((emaillist == null) ? 0 : emaillist.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result
                + ((notesList == null) ? 0 : notesList.hashCode());
        result = prime * result
                + ((phonelist == null) ? 0 : phonelist.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof ContactsMainBean)) {
            return false;
        }
        ContactsMainBean other = (ContactsMainBean) obj;
        if (addressbean == null) {
            if (other.addressbean != null) {
                return false;
            }
        } else if (!addressbean.equals(other.addressbean)) {
            return false;
        }
        if (emaillist == null) {
            if (other.emaillist != null) {
                return false;
            }
        } else if (!emaillist.equals(other.emaillist)) {
            return false;
        }
        if (name == null) {
            if (other.name != null) {
                return false;
            }
        } else if (!name.equals(other.name)) {
            return false;
        }
        if (notesList == null) {
            if (other.notesList != null) {
                return false;
            }
        } else if (!notesList.equals(other.notesList)) {
            return false;
        }
        if (phonelist == null) {
            if (other.phonelist != null) {
                return false;
            }
        } else if (!phonelist.equals(other.phonelist)) {
            return false;
        }
        return true;
    }

    public void setAddressbean(List<AddressBean> addressbean) {

        if (this.addressbean != null && this.addressbean.size() > 0) {
            this.addressbean.addAll(addressbean);
        } else {
            this.addressbean = addressbean;
        }
        // this.addressbean = addressbean;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        // return getName()+":"+getPhonelist();
        return getName() + ":" + getPhonelist() + ":" + getEmaillist() + ":"
                + getAddressbean() + ":" + getNotesList() + ":"
                + name.hashCode() + ":" + phonelist.hashCode() + ":"
                + emaillist.hashCode() + ":" + notesList.hashCode();
    }

}

I have overridden hashcode and equals method in phonebean,emailbean,addressbean.

Adding beanobject code:

  public class PhoneBean {

    String type;
    String number;

    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((number == null) ? 0 : number.hashCode());
        //result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PhoneBean other = (PhoneBean) obj;
        if (number == null) {
            if (other.number != null)
                return false;
        } else if (!number.equals(other.number))
            return false;
//      if (type == null) {
//          if (other.type != null)
//              return false;
//      } else if (!type.equals(other.type))
//          return false;
        return true;
    }

@Override
public String toString() {
    // TODO Auto-generated method stub
    return getNumber();
}

}

email bean :

public class EmailBean {

    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getEmailType() {
        return emailType;
    }
    public void setEmailType(String emailType) {
        this.emailType = emailType;
    }
    String email;
    String emailType;
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((email == null) ? 0 : email.hashCode());
        result = prime * result
                + ((emailType == null) ? 0 : emailType.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        EmailBean other = (EmailBean) obj;
        if (email == null) {
            if (other.email != null)
                return false;
        } else if (!email.equals(other.email))
            return false;
        if (emailType == null) {
            if (other.emailType != null)
                return false;
        } else if (!emailType.equals(other.emailType))
            return false;
        return true;
    }

}

address bean :

public class AddressBean {

     String poBox;
     String street;
     String city;
     String state;
     String postalCode;
     String country;
     String addresstype;
    public String getPoBox() {
        return poBox;
    }
    public void setPoBox(String poBox) {
        this.poBox = poBox;
    }
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getPostalCode() {
        return postalCode;
    }
    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getAddresstype() {
        return addresstype;
    }
    public void setAddresstype(String addresstype) {
        this.addresstype = addresstype;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((addresstype == null) ? 0 : addresstype.hashCode());
        result = prime * result + ((city == null) ? 0 : city.hashCode());
        result = prime * result + ((country == null) ? 0 : country.hashCode());
        result = prime * result + ((poBox == null) ? 0 : poBox.hashCode());
        result = prime * result
                + ((postalCode == null) ? 0 : postalCode.hashCode());
        result = prime * result + ((state == null) ? 0 : state.hashCode());
        result = prime * result + ((street == null) ? 0 : street.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AddressBean other = (AddressBean) obj;
        if (addresstype == null) {
            if (other.addresstype != null)
                return false;
        } else if (!addresstype.equals(other.addresstype))
            return false;
        if (city == null) {
            if (other.city != null)
                return false;
        } else if (!city.equals(other.city))
            return false;
        if (country == null) {
            if (other.country != null)
                return false;
        } else if (!country.equals(other.country))
            return false;
        if (poBox == null) {
            if (other.poBox != null)
                return false;
        } else if (!poBox.equals(other.poBox))
            return false;
        if (postalCode == null) {
            if (other.postalCode != null)
                return false;
        } else if (!postalCode.equals(other.postalCode))
            return false;
        if (state == null) {
            if (other.state != null)
                return false;
        } else if (!state.equals(other.state))
            return false;
        if (street == null) {
            if (other.street != null)
                return false;
        } else if (!street.equals(other.street))
            return false;
        return true;
    }


}

The Weired thing is if i sysout below code in tostring() of class. i get below result

return getName() + ":" + getPhonelist() + ":" + getEmaillist() + ":"
                + getAddressbean() + ":" + getNotesList() + ":"
                + name.hashCode() + ":" + phonelist.hashCode() + ":"
                + emaillist.hashCode() + ":" + notesList.hashCode();

Result:

12-12 00:25:20.133: I/System.out(2317): *Dial Airtel:[321]:[]:[]:[]:346070743:50672:1:1
12-12 00:25:20.133: I/System.out(2317): *Dial Airtel:[321]:[]:[]:[]:346070743:50672:1:1
12-12 00:25:20.143: I/System.out(2317): *Dial Airtel:[321]:[]:[]:[]:346070743:50672:1:1
12-12 00:25:20.143: I/System.out(2317): *Dial Airtel:[321]:[]:[]:[]:346070743:50672:1:31

Instead of building your own hashes and equals, consider using (from org.apache.commons.lang.builder) the EqualsBuilder and HashCodeBuilder classes, which will do the right thing.

http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/EqualsBuilder.html

http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/HashCodeBuilder.html

For example you may use:

public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(this);
}

I think you're overdoing the hashcode implementations. All you need to do is return a value that indicates the object might be equal to another object with the same hashcode value.

For each class choose an attribute whose value will not change (usually an id of some sort) and for that class's hashCode() method just return the hashcode for that particular value.

Then for the equals() method you just compare the values for that attribute.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM