如何实现hashCode和equals方法
我应该如何在Java中为以下类实现hashCode()
和equals()
?如何实现hashCode和equals方法
class Emp
{
int empid ; // unique across all the departments
String name;
String dept_name ;
String code ; // unique for the department
}
>来源 - >生成hashCode()和equals()方法给出了这样的:
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (code == null ? 0 : code.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Emp))
return false;
Emp other = (Emp) obj;
return code == null ? other.code == null : code.equals(other.code);
}
我已经选择代码作为唯一字段
嗯......我通常会比较equals()方法中的所有字段,除非你真的有很强的理由不去... – 2010-01-25 13:04:11
因此,如果来自不同部门的两个'Emp'具有相同的代码,它们是相等的吗?你至少需要在这个实现中添加'dept_name'。 – 2010-01-25 13:21:05
我接受这个答案,因为我知道需要做什么。jutky假定代码作为唯一标识符。 – Vidya 2010-01-25 13:24:10
如果代码是唯一的(即自己的业务),最好只使用代码equals和hashCode - 这是很好的做法,从对象ID单独的业务密钥(代码)(ID)。
这里是一个不错的读取:Hibernate Documentation: Equals and HashCode(不仅适用于Hibernate的本身)
这似乎是一个部门的独特之处,所以建议部门可以共享相同的“代码”。无论如何,如果你问我一个相当含糊的问题。 – 2010-01-25 12:59:53
什么是您在equals中使用的值,以确定两个对象是否相同,是您需要用来创建哈希码的值。
public boolean equals(Object o) {
boolean result = false;
if(o instanceof CategoryEnum) {
CategoryEnum ce = (CategoryEnum) o;
result = ce.toString().equals(name);
}
return result;
}
public int hashCode()
{
int hash = 6;
hash += 32 * name.hashCode();
return hash;
}
(从我这里没有-1)这不完全正确。只使用hashCode的一个子集是完全合法的(例如代码和名称用于equals,只用于hashCode)。使用一个常量hashCode('public int hashCode(){return 42;}')甚至是合法的 - 它破坏了哈希集合(HashMap,HashSet,...)的性能,但是它们保持正常工作。所以它比无效的hashCode方法更好。唯一的规则是:如果两个对象相等('a.equals(b)'),它们必须具有相同的散列码('a.hashCode()== b.hashCode()')。如果它们不相等,则散列码可能仍然相等。 – sfussenegger 2010-01-25 14:40:14
equals()和hashcode(),它们有很多不同的地方。 equals(),如果我们不从Object中覆盖它,它表示两个变量是否指向同一个对象堆?
public Class Student(){
private int id;
private name;
public Student(int id,String name){
this.name=name;
this.id=id;
}
public void main(String[] args){
Student A=new Student(20,'Lily');
Student B=new Student(20,'Lily');
boolean flag=A.equals(B)//flag=flase;
/*
*Although they attribute the same, but they are two different objects, they point to different memory
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Student s=(Student)obj;
return new Integer(this.id).equals(new Integer(s.id))&&this.name.equals(s.name);
}
/**
*Sometimes even though we Override the equals, but we still can not determine whether the *two objects the same,
*In the collection object, such as HashSet, this time we have to Override the hashoCode()
*/
public int hashCode(){
return id + name.hashCode() ;
}
试试这个代码,使用org.apache.commons.lang3.builder
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
append(empid).
append(name).
append(dept_name).
append(code).
toHashCode();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Person))
return false;
Emp rhs = (Emp) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
isEquals();
}
番石榴辅助方法来创建它们。您告诉它哪些字段需要考虑,它会为您处理空值,并对散列码进行素数计算。
IDE也可以根据您选择的字段生成它们。
把它委托给这样的工具的好处是你可以得到一个标准的解决方案,并且不用担心在你的项目中遍布各种实现的bug和维护。
下面是使用番石榴和生成一个的IntelliJ插件的示例:https://plugins.jetbrains.com/plugin/7244?pr=
即没有Java源代码。或者你创建了自己的叫做'string'的类吗?你真的应该看看这个:http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html – 2010-01-25 12:57:46
我看到Joachim在你的代码示例中改变了一些错误。不过,我建议查看我之前评论中发布的链接。 – 2010-01-25 13:01:19
我正在使用java的String类 – Vidya 2010-01-25 13:02:22