[英]Overrriding equal() and hashCode() method of domain Class in Java
I have a domain Class named Subscriber
and its definition is something like this: 我有一个名为
Subscriber
的域类,其定义是这样的:
public class Subscriber {
private long id;
private String email;
private String subscriberName;
private Topic subscribingTopic;
//other attributes and getters setters.
}
public class Topic{
private long id;
private String topicName; //unique
}
My problem is I need to override the equal() and hashCode() methods of this Subscriber class. 我的问题是我需要重写此Subscriber类的equal()和hashCode()方法。 Overriding equal() is somewhat easy task (just comparing basic attributes, in this case there are three of them).
覆盖equal()有点容易(只是比较基本属性,在这种情况下有三个)。 But I am facing problems while overriding hashCode() method.
但是我在覆盖hashCode()方法时遇到了问题。 How I can write hashCode() that I can trust to be used by hibernate safely, while managing my domains.
我如何编写可以信任的hashCode(),以便在管理我的域时可以安全地被hibernate使用。 Can I trust IDE generated one?
我可以信任IDE生成的吗?
Any help will be appreciated and thanks in advance! 任何帮助将不胜感激,并在此先感谢!
If you're on Java 7, you could use Objects.hash()
: 如果您使用的是Java 7,则可以使用
Objects.hash()
:
return Objects.hash(email, subscriberName, subscribingTopic);
If you're on Java 6, you could use Guava's Objects.hashCode()
method (the same way as above). 如果您使用的是Java 6,则可以使用Guava的
Objects.hashCode()
方法(与上述方法相同)。
If you're on Java 5, you could use Apache commons-lang HashCodeBuilder
class to help you. 如果您使用的是Java 5,则可以使用Apache commons-lang
HashCodeBuilder
类来帮助您。
You can use IDE like Eclipse to generate hashCode
method for you. 您可以使用像Eclipse这样的IDE来为您生成
hashCode
方法。 One sample hashCode
method is below: 下面是一个示例
hashCode
方法:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
result = prime
* result
+ ((subscriberName == null) ? 0 : subscriberName.hashCode());
result = prime
* result
+ ((subscribingTopic == null) ? 0 : subscribingTopic
.hashCode());
return result;
}
You need to create a similar hashCode
method in Topic
class as well. 您还需要在
Topic
类中创建类似的hashCode
方法。
Per Object#hashCode
API: 每个
Object#hashCode
API:
The general contract of hashCode is:
hashCode的一般约定为:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.
在Java应用程序的执行过程中,只要在同一对象上多次调用它,则hashCode方法必须一致地返回相同的整数,前提是未修改该对象的equals比较中使用的信息。 This integer need not remain consistent from one execution of an application to another execution of the same application.
从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
- If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
如果根据equals(Object)方法,两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
- It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.
根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要在两个对象中的每个对象上调用hashCode方法必须产生不同的整数结果。 However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
Its general practice to use prime number 31 and combine the attribute values in a*31^(x)+b*31^(x-1)+..c to achieve the unique number for the object. 它的一般做法是使用质数31,并在a * 31 ^(x)+ b * 31 ^(x-1)+ .. c中组合属性值以获得对象的唯一编号。 In the process, you can use the
hashCode
method of underline object. 在此过程中,可以使用下划线对象的
hashCode
方法。 The above method also does the same. 上面的方法也一样。
How I can write hashCode() that returns unique hash value using the specified three attributes?
如何编写使用指定的三个属性返回唯一哈希值的hashCode()?
It does not have to be unique, only distinct enough to distinguish among non-equal values. 它不必是唯一的,只需足够明显以区分不相等的值即可。
One common way is to use component hash codes, and combine them as ((h1*31)+h2)*31+h3
and so on. 一种常见的方法是使用组件哈希码,并将它们组合为
((h1*31)+h2)*31+h3
,依此类推。
Here is how you do it: first, define hashCode
for the Topic
, like this: 操作方法如下:首先,为
Topic
定义hashCode
,如下所示:
int hashCode() {
return topicName.hashCode()*31 + (int)id;
}
You need to override Topic
's equals
as well! 您还需要覆盖
Topic
的equals
!
Then define the hash code for Subscriber
, like this: 然后为
Subscriber
定义哈希码,如下所示:
int hashCode() {
return id.hashCode()*31*31*31
+ email.hashCode()*31*31
+ subscriberName.hashCode()*31
+ subscribingTopic.hashCode();
}
The code above assumes that the constructor initializes all components of the Subscriber
to be non-null. 上面的代码假定构造函数将
Subscriber
所有组件初始化为非null。
The hashCode()
does not need to be unique. hashCode()
不必唯一。 The only thing is that it must return the same hashcodes for obj1
and obj2
, if obj1.equals(obj2)
. 唯一的问题是,如果
obj1.equals(obj2)
,则必须为obj1
和obj2
返回相同的哈希obj1.equals(obj2)
。 You can just return email.hashCode()
for example. 例如,您可以仅返回
email.hashCode()
。
Perfect hash function does not exist - it is not possible to return different hashcodes for every pair of different elements. 完美的哈希函数不存在-无法为每对不同的元素返回不同的哈希码。 Java uses
equals
for further differentiation(if the hashcodes are the same). Java使用
equals
进行进一步区分(如果哈希码相同)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.