Overriding hashcode and equals method in java?

16,035

Solution 1

are you looking something like following? Just try it, as from your question i think you want to compare contents of your Sample class also.

class Sample implements java.io.Serializable{

    //POJO with two fields and getters/setters

    private String name;
    private Integer id;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    //This POJO does not override equals() and hashCode()
}

public class Beta implements Comparable{
    private Sample sample;

    public Sample getSample() {
        return sample;
    }

    public void setSample(Sample sample) {
        this.sample = sample;
    }

    @Override
    public int compareTo(Object o) {

        if(!(o instanceof Beta)){
            return -1;
        }
        }if(((Beta)o).getSample().getName().equals(this.sample.getName())){
                return 0; // return true if names are equal
            }
            if(((Beta)o).getSample().getId().equals(this.sample.getId())){
            //if name are notequal and IDs are equal, do what you need to do
            }
        return -1;
    }

    public static void main(String[] args) {
        Beta b = new Beta();
        Sample s = new Sample();
        s.setId(10);
        s.setName("Name1");
        b.setSample(s);

        Beta b2 = new Beta();
        Sample s2 = new Sample();
        s2.setId(20);
        s2.setName("Name2");
        b2.setSample(s2);

        System.out.println(b2.compareTo(b));

        Beta b3 = new Beta();
        Sample s3 = new Sample();
        s3.setId(10);
        s3.setName("Name1");
        b3.setSample(s3);

        System.out.println(b3.compareTo(b));
    }
}

Overriding approach

class Sample implements java.io.Serializable{

    //POJO with two fields and getters/setters

    private String name;
    private Integer id;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    //This POJO does not override equals() and hashCode()
}

public class Beta /*implements Comparable*/{
    private Sample sample;

    public Sample getSample() {
        return sample;
    }

    public void setSample(Sample sample) {
        this.sample = sample;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Beta other = (Beta) obj;

        if ((this.getSample() == null) && (other.getSample() == null)){
            return true;
        }
        if ((this.getSample().getId().equals(other.getSample().getId())) && (this.getSample().getName().equals(other.getSample().getName()))) {
            return true;
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + (this.getSample().getName() != null ? this.getSample().getName().hashCode() : 0);
        hash = 53 * hash + (this.getSample().getId() != null ? this.getSample().getId().hashCode() : 0);
        return hash;
    }


/*  @Override
    public int compareTo(Object o) {

        if(!(o instanceof Beta)){
            return -1;
        }
        if(((Beta)o).getSample().getId().equals(this.sample.getId()) && ((Beta)o).getSample().getName().equals(this.sample.getName())){
            return 0;
        }
        return -1;
    }*/

    public static void main(String[] args) {
        Beta b = new Beta();
        Sample s = new Sample();
        s.setId(10);
        s.setName("Name1");
        b.setSample(s);

        Beta b2 = new Beta();
        Sample s2 = new Sample();
        s2.setId(20);
        s2.setName("Name2");
        b2.setSample(s2);

        System.out.println(b2.equals(b));

        Beta b3 = new Beta();
        Sample s3 = new Sample();
        s3.setId(10);
        s3.setName("Name1");
        b3.setSample(s3);

        System.out.println(b3.equals(b));
    }

Solution 2

If you don't explicitly override .equals(), they will be compared based solely off of their references (despite not having a equals(), every object inherits one from Object). If you only want B to be compared based off of Sample, then simply do the following:

@Override
public boolean equals(Object o)
{
     if (o istanceof B)
     {
         return sample.equals(o.sample)
     }

     return false;
}

Additionally, you should then override hashCode() (and compareTo()) to maintain the contract between equals() and hashCode(). Hence, you should also have the following:

@Override
public int hashCode()
{
    return sample.hashCode();
}

EDIT (in response to comment):

My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!

Determining whether Samples are equivalent should be handled in Sample, by overriding equals(). If equals() for Sample bases off of name and id, then you're fine. If you want to compare Samples in B differently than they are normally compared, then you're not going to be able to maintain the contract between equals() and hashCode() for B if you use hashCode() or equals() from Sample, which means that your hashCode() and equals() for B should be cannot call equals() or hashCode() from Sample. See this tutorial for how to override based on specific fields.

Share:
16,035
user755806
Author by

user755806

Updated on June 16, 2022

Comments

  • user755806
    user755806 almost 2 years

    I have the classes below:

    public class Sample implements java.io.Serializable{
    
      //POJO with two fields and getters/setters
    
       private String name;
       private Integer id;
    
       //This POJO does not override equals() and hashCode()
    }
    
    public class B{
     private Sample sample;
    
      //here i need override hashcode and equals() based on **sample** property.
    
    
    }
    

    When i tried overriding equals() and hashCode() in the B class I got the error below in Eclipse.

    The field type com.mypackage.Sample does not implement hashCode() and equals() - The resulting code may not work correctly.

    Now how can I compare two B instances whether equals or not based on the Sample property? I cannot modify Sample class.

  • user755806
    user755806 over 10 years
    I tried. But still i get "The field type com.mypackage.Sample does not implement hashCode() and equals() - The resulting code may not work correctly". any suggestions?
  • Steve P.
    Steve P. over 10 years
    @user755806 This definitely works, I believe that your IDE is simply telling you that you're not explicitly overriding hashCode() and equals(). Make sure that you have also overridden hashCode() for B--I made an edit stating how to do this. If this is not done, then you will not be maintaining the contract of equals() and hashCode(). If your IDE still yells at you, it's just a warning to make sure that you understand that for Sample you're using the default methods instead of overriding.
  • user755806
    user755806 over 10 years
    Steve, thanx for your reply. My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!
  • Steve P.
    Steve P. over 10 years
    @user755806 You're asking multiple questions here...This should be handled in Sample. As in overriding equals() from Sample. If this is not the way that Samples should normally be compared, or you are unable to do that, then you're not going to be able to maintain the equals() and hashCode() contract, which means that you cannot do what you want to do. See this tutorial for how to override based on specific fields.
  • user755806
    user755806 over 10 years
    VD, yes exactly this is what i was looking for.My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!
  • dev2d
    dev2d over 10 years
    i have edited the code for your requirement, you can refer overriding approach from stackoverflow.com/questions/8180430/…
  • dev2d
    dev2d over 10 years
    i have also edited the code for overriding hashcode and equals methods