覆盖java中的hashcode和equals方法?

时间:2013-12-10 11:26:23

标签: java equals hashcode java-ee-7

我有以下课程:

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.


}

当我尝试在 B 类中重写equals()和hashCode()时,我在Eclipse中得到了以下错误。

  

字段类型com.mypackage.Sample未实现hashCode()和equals() - 生成的代码可能无法正常工作。

现在如何基于Sample属性比较两个 B 实例是否等于? 我无法修改Sample类。

2 个答案:

答案 0 :(得分:2)

你看起来像下面的东西吗?试试吧,从您的问题来看,我认为您也希望比较Sample类的内容。

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));
    }
}

覆盖方法

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));
    }

答案 1 :(得分:1)

如果您没有明确覆盖.equals(),它们将仅根据其引用进行比较(尽管没有equals(),每个对象都从Object继承)。如果您只希望B根据Sample进行比较,则只需执行以下操作:

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

     return false;
}

此外,您应该覆盖hashCode()(和compareTo())以在equals()hashCode()之间保持contract。因此,您还应该具备以下条件:

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

编辑(回应评论):

  

我的要求是首先我需要检查equals属性与“name”   Sample的财产。 IF名称等于,则两个对象都相等。   如果名称不等于那么我需要检查“ID”是否相等   Sample的财产。我怎样才能做到这一点?谢谢!

确定Samples是否相同应通过覆盖Sampleequals()中处理。如果equals()的{​​{1}}基于Samplename,那么您就可以了。如果您想要将idSamples进行比较,而不是通常比较它们,那么您将无法维持Bequals()之间的合同{ {1}}如果您使用hashCode()中的BhashCode(),则表示您equals()的{​​{1}}和Sample无法调用来自hashCode()的{​​{1}}或equals()。有关如何根据特定字段覆盖,请参阅此tutorial