为什么重写了equals()方法后,要重写hashcode方法
因为关于equals方法与hashcode方法有两个约定
(1)equals方法返回值为true的两个对象,它们的hashcode方法也应返回相同的值
(2)equals方法返回值为false的两个对象,它们的hashcode方法不要求一定返回不同的值。
对于第一条考虑一个 PhoneNumber对象
package leetcode.tag.backtrack;
import java.util.HashMap;
import java.util.Map;
public class PhoneNumber {
private int prefix;
private int num;
public PhoneNumber(int prefix, int num) {
this.prefix = prefix;
this.num = num;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof PhoneNumber)) {
return false;
}
PhoneNumber tmp = (PhoneNumber)obj;
return (tmp.prefix == prefix) && (tmp.num == num);
}
public static void main(String[] args) {
Map<PhoneNumber, String> map = new HashMap<>();
map.put(new PhoneNumber(183, 12345678), "Jenny");
System.out.println(map.get(new PhoneNumber(183, 12345678)));
}
}
若重写了equals方法,却没有重写hashcode方法后,返回为Null。
因为put方法,根据创建的对象的hashcode计算哈希桶索引。
get方法,根据传入的key的hashcode计算哈希桶索引,由于hashcode方法没有被重写,因为equals方法返回为true的两个对象,在调用hashcode方法时返回的是不同的值,get方法计算的索引当然不是put方法存入的那个索引,因为返回值当然是Null。
hashcoe方法重写的要点
(1)为相等的对象,返回相同的值
(2)为不相等的对象,尽量返回不同的值(因为有哈希碰撞)
@Override
public int hashCode() {
int result = Integer.hashCode(prefix);
result = 31 * result + Integer.hashCode(prefix);
result = 31 * result + Integer.hashCode(num);
return result;
}
当我们重写了hashcode方法后,再次执行main方法,可正确的返回Jenny
Jenny