以下代码根据《Java核心技术卷一》整理得来,都是这本书所建议使用的equals和hashcode的标准代码格式。
大家以后要重写equals和hashcode都按照这个模板来就行了。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
/**
* Created by keboom on 2020/8/15.
*/
public class EqualsTest {
public static void main(String[] args) throws ParseException {
People people1 = new People("ke", 12, new SimpleDateFormat("yyyy-MM-dd").parse("2000-07-01"));
People people2 = new People("ke", 12, new SimpleDateFormat("yyyy-MM-dd").parse("2000-07-01"));
System.out.println(people1.equals(people2));
System.out.println(people1.hashCode() + "--" + people2.hashCode());
System.out.println(people1);
System.out.println(people2);
//true
//311440781--311440781
//others.People@1290358d
//others.People@1290358d
}
}
class People {
private String name;
private Integer id;
private Date birthday;
public People(String name, Integer id, Date birthday) {
this.name = name;
this.id = id;
this.birthday = birthday;
}
@Override
public boolean equals(Object otherObject) {
if (otherObject == this) {
return true;
}
if (otherObject == null) {
return false;
}
/*
比较 this 与 otherObject 是否属于同一个类。
如果 equals 的语义在每个子类中有所改变, 就使用 getClass 检测 :
if ( getClass ( ) ! = otherObject . getCIassO ) return false ;
如果所有的子类都拥有统一的语义, 就使用instanceof 检测 :
if ( ! ( otherObject instanceof ClassName ) ) return false ;
*/
if (this.getClass() != otherObject.getClass()) {
return false;
}
People other = (People) otherObject;
return name.equals(other.name)
&& id == other.id
&& birthday.equals(other.birthday);
}
//需要组合多个散列值时,可以调用Objects.hash并提供多个参数。
//这个方法会对各个参数调用Objects.hashCode,并组合这些散列值。
@Override
public int hashCode() {
return Objects.hash(name, id, birthday);
}
}
为什么重写equals方法也必须要重写hashcode方法?
如果你的类不会用到HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,那么你写不写hashCode都行。
如果你的类会用到HashSet等等这些,那么你就必须重写equals时也必须重写hashcode。如果你将你的类放到HashSet中,但你的类没有重写hashcode方法,即使你这个类的两个实例内容一模一样,equals结果也为true。但是hashset中仍然认为这两个内容一样的实例是不相等的,也就是说hashset会出现两个一样的元素,比如这个hashset: [(eee, 100), (eee, 100), (aaa, 200)]