一、定义
hashcodes不等 equals必定不等;
equals相等,hashcodes必定相等。
二、原因
hashcodes是为了hash表使用的。
假想:如果一个不允许元素重复(HashSet),那么怎么确定将要添加的元素集合中不存在?
1、错误做法,每个对象去equals一下,虽然可以达到效果,但是却不可采用,如果集合中已经存在几万个元素,那么就得euqals几万遍,太闹心了,花费时间不允许;
2、正确做法,先比较每个对象hashcodes方法,如果相同,再进行equals比较。
三、如何重写
1、hashcode()
Google首席Java架构师Joshua Bloch在他的著作《Effective Java》中提出了一种简单通用的hashCode算法
1. 初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;
2. 选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算:
(1) 如果是boolean值,则计算f ? 1:0
(2) 如果是byte\char\short\int,则计算(int)f
(3) 如果是long值,则计算(int)(f ^ (f >>> 32))
(4) 如果是float值,则计算Float.floatToIntBits(f)
(5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int
(6)如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode值为0
(7)如果是数组,那么需要为每个元素当做单独的域来处理。如果你使用的是1.5及以上版本的JDK,那么没必要自己去重新遍历一遍数组,java.util.Arrays.hashCode方法包含了8种基本类型数组和引用数组的hashCode计算,算法同上。
@Override
public int hashCode() {
int result = 17;
result = result * 31 + name.hashCode();
result = result * 31 + age;
return result;
}
备注 31可以 由i*31== (i<<5)-1来表示,使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits!
2、重写euqals()
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null)
return false;
if (!(obj instanceof User)) {
return false;
}
MyClass o = (MyClass)obj;
return '对象中每个属性比较';
}
参考:https://blog.csdn.net/zhengchao1991/article/details/78916471