一、equals方法
1. 简介:Object类中的equals方法用于判断一个对象是否等于另外一个对象(判断是否具有相同的引用),当实际开发中经常根据两个对象中的个别域来判断两个对象是否相同。
2. 重写规则:
1 public boolean equals(Object otherObj) {
2 //检测this与otherObj是否引用同一个对象
3 if (this == otherObj) {
4 return true;
5 }
6 //检测otherObj是否为空
7 if (otherObj == null) {
8 return false;
9 }
10
11 /*
12 注意:以下比较规则按实际情况二选一
13 */
14 //比较this与otherObj是否属于同一个类,如果equals的语义在每个子类中有所改变,就用getClass检测
15 if (this.getClass() != otherObj.getClass()) {
16 return false;
17 }
18 //如果所有的子类都拥有统一的语义,就用instanceof检测
19 if (!(otherObj instanceof Employee)) {
20 return false;
21 }
22
23 //类型强转,进行域比较
24 Employee employee = (Employee)otherObj;
25 return this.salary == employee.salary
26 && Objects.equals(this.name, employee.name) //如果用equals比较会发生一种情况:当比较双方都为null时返回true,故用Objects的equals方法
27 && Objects.equals(this.hireDay, employee.hireDay);
28 }
instanceof和getClass的选择:
假设有e.equals(m),其中e为Employee的对象,m是一个Manager对象,两个对象具有相同的姓名,薪水,如果在Employee.equals中用instanceof进行检测,则返回true,然而反过来是返回false,但根据equals的对称性,必须返回true,故在这里不会考虑Manager特有的域,只会考虑公有域。在这个例子中,可以得出如果子类能够拥有自己的相等概念,则需要用getClass进行判断,例如两个Manager对象所对应的姓名,薪水,但奖金不同来判断二者对象不同;如果由超类决定相等的概念,那么就得用instanceof,例如使用Employee的ID。
子类的重写规则(父类已经重写):
1 public boolean equals(Object otherObj) {
2 if (!super.equals(otherObj)) {
3 return false;
4 }
5 Manager manager = (Manager)otherObj;
6 return this.bonus == manager.bonus;
7 }
二、hashCode方法
1. 简介:对象导出的一个整数值。
· 2. 重写规则:
1 public int hashCode() {
2 return 7 * Objects.hashCode(name)
3 + 11 * Double.hashCode(salary)
4 + 13 * Objects.hashCode(hireDay);
5 }
或
1 public int hashCode() {
2 return Objects.hash(hireDay, name, hireDay);
3 }
注意:1. 子类重写要加上super.hashCode()。2. equals与hashCode的定义必须一致,例如用定义的equals比较雇员的ID,那么hashCode方法就需要散列ID,而不是雇员的姓名等。