equals方法,hashCode方法

时间:2021-10-16 16:08:42

需求1: 如果两个empolyee的 age,name,hireDate相等,则认为是同一个empolyee

import java.util.Date;

public class Empolyee{
private int age;
private String name;
private Date hireDate;

public Empolyee(int age,String name,Date hireDate){
this.setAge(age);
this.setName(name);
this.setHireDate(hireDate);
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String toString(){
return "age: " + age + ",name:" + name + ",hireDate:" + hireDate;
}

public Date getHireDate() {
return hireDate;
}

public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
}

public class EmpolyeeTest {
public static void main(String[] args) throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Empolyee e1 = new Empolyee(26, "Lilei",sdf.parse("2012-04-22 09:13:37"));
Empolyee e2 = new Empolyee(30, "Mike", sdf.parse("2013-04-21 12:36:39"));
Empolyee e3 = new Empolyee(30, "Mike", sdf.parse("2013-04-21 12:36:39"));

System.out.println("does e1 equals e2 ? " + e1.equals(e2));
System.out.println("does e2 equals e3 ? " + e2.equals(e3));

}
}


运行EmpolyeeTest.java

System.out.println("does e1 equals e2 ? " + e1.equals(e2)); //false
System.out.println("does e2 equals e3 ? " + e2.equals(e3)); //false

e2.equals(e3) 返回结果为false,与期望的true不一致。

解决方案:重载equals方法

/**
* 一个完整的override equals方法共有4步,如果有父类,先调用super.equals()
*/
@Override
public boolean equals(Object otherObject){
//1. 引用是否相同
if(this == otherObject){
return true;
};

//2. 是否为null
if(otherObject == null){
return false;
}
// 3.是否属于同一个类
if(this.getClass() !=otherObject.getClass() ){
return false;
}

// 4.将otherObject 转换为相应的类类型变量
Empolyee other = (Empolyee)otherObject;

return name.equals(other.name)
&& age == other.age
&& hireDate.equals(other.hireDate);

}

重新运行EmpolyeeTest.java

System.out.println("does e1 equals e2 ? " + e1.equals(e2)); //false
System.out.println("does e2 equals e3 ? " + e2.equals(e3)); //true

 需求2:将empolyee存储在集合HashSet中

在EmpolyeeTest.java添加下面代码

 

      System.out.println("e2 hashcode: " + e2.hashCode() + ",e3 hashcode: " + e3.hashCode());

Set<Empolyee> empolyeeSet = new HashSet<Empolyee>();
empolyeeSet.add(e1);
empolyeeSet.add(e2);
empolyeeSet.add(e3);

for(Empolyee e:empolyeeSet ){
System.out.println(e.toString());
}

输出结果为:

e2 hashcode: 1046495759,e3 hashcode: 563152583
age: 26,name:Lilei,hireDate:Sun Apr 22 09:13:37 CST 2012
age: 30,name:Mike,hireDate:Sun Apr 21 12:36:39 CST 2013
age: 30,name:Mike,hireDate:Sun Apr 21 12:36:39 CST 2013

问题:集合中不允许存在相同元素。按照最初的逻辑:如果两个empolyee的 age,name,hireDate相等,则认为是同一个empolyee,那么e2,e3只保存一个即可。

解决方案:覆盖hashCode方法。在《effective java》有条规则:覆盖equals方法是总要覆盖hashCode方法

在Emoplyee.java中添加

@Override
/**
* 重载equals方法时,必须重载hashCode方法。因为Object.hashCode的约定:相等的对象,必须具有相同的hashCode。
* hashCode()方法何时被调用?参考http://www.cnblogs.com/batys/archive/2011/10/25/2223942.html
* Set中不允许存在相同的元素。当对象要存储到Set集合中时,调用对象的hashCode方法,确定该集合存储的位置。
*/
public int hashCode(){
return name.hashCode() + hireDate.hashCode() + age;
}

输出结果:

e2 hashcode: 721796890e3 hashcode: 721796890
age: 30,name:Mike,hireDate:Sun Apr 21 12:36:39 CST 2013
age: 26,name:Lilei,hireDate:Sun Apr 22 09:13:37 CST 2012

关于hashCode方法的详细解释,参考: http://www.ibm.com/developerworks/cn/java/j-jtp05273/