在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
Overriding hashcode and equals method in java?
提问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 B
to 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 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 tutorialfor how to override based on specific fields.
确定是否Samples
是等价的,应在办理Sample
,通过重写equals()
。如果equals()
以和为Sample
基础,那么你很好。如果您想以与通常比较的方式不同的方式进行比较,那么如果您使用or from ,则您将无法维护and for之间的合同,这意味着您的and for应该不能调用或from 。有关如何根据特定字段进行覆盖,请参阅本教程。name
id
Samples
B
equals()
hashCode()
B
hashCode()
equals()
Sample
hashCode()
equals()
B
equals()
hashCode()
Sample