在java中覆盖hashcode和equals方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20493208/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:19:30  来源:igfitidea点击:

Overriding hashcode and equals method in java?

javaequalshashcodejava-ee-7

提问by user755806

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 Bclass I got the error below in Eclipse.

当我尝试覆盖B类中的 equals() 和 hashCode() 时,我在 Eclipse 中收到以下错误。

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

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

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

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

采纳答案by dev2d

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.

你看起来像下面这样吗?试试吧,从你的问题来看,我认为你也想比较 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));
    }
}

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

回答by Steve P.

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 Bto be compared based off of Sample, then simply do the following:

如果您没有显式覆盖.equals(),它们将仅基于它们的引用进行比较(尽管没有equals(),但每个对象都从 继承一个Object)。如果您只想B根据 of 进行比较Sample,则只需执行以下操作:

@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 contractbetween equals()and hashCode(). Hence, you should also have the following:

此外,您应该然后覆盖hashCode()(和compareTo()),以维持合同之间equals()hashCode()。因此,您还应该具备以下条件:

@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!

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

Determining whether Samplesare equivalent should be handled in Sample, by overriding equals(). If equals()for Samplebases off of nameand id, then you're fine. If you want to compare Samplesin Bdifferently than they are normally compared, then you're not going to be able to maintain the contract between equals()and hashCode()for Bif you use hashCode()or equals()from Sample, which means that your hashCode()and equals()for Bshould be cannot call equals()or hashCode()from Sample. See this tutorialfor how to override based on specific fields.

确定是否Samples是等价的,应在办理Sample,通过重写equals()。如果equals()以和为Sample基础,那么你很好。如果您想以与通常比较的方式不同的方式进行比较,那么如果您使用or from ,则您将无法维护and for之间的合同,这意味着您的and for应该不能调用或from 。有关如何根据特定字段进行覆盖,请参阅本教程nameidSamplesBequals()hashCode()BhashCode()equals()SamplehashCode()equals()Bequals()hashCode()Sample