目录
- 1 hash
- 2 hashcode
- 3 hashcode的作用
- 4 equals()和hashcode的关系
- 5 为什么equals()重写的话,建议也一起重写hashcode方法?
1 hash
- hash是一种函数,一般翻译为散列,是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是hashcode(散列值/哈希码);
- 这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值;
- 简单地说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
常用hash函数:直接取余法、乘法取整法、平方取中法等。
2 hashcode
把任意长度的输入通过hash算法变换成固定长度的输出,该输出就是hashcode。
3 hashcode的作用
hashcode的存在主要是为了查找的快捷性。
比如:我们要存放1000个不一样的数字,用最笨的方法,就是存一个数字,就遍历一遍,看有没有相同的数,当存了100个数字,开始存第101个数的时候,就需要跟100个数字进行比较,这样就很消耗时间。
如果用hashcode来记录对象的位置,假设hash表中有1、2、3、4、5、6、7、8个位置,存第一个数,hashcode为1,该数就放在hash表中1的位置,存到100个数字,hash表中8个位置会有很多数字了,1中可能有20个数字,存第101个数时,先得到该数的hashcode,假设为1,那么就有20个数字和它的hashcode相同,它只需要跟这20个数字相比较(equals()),这样比较的次数就少了很多,提高了效率。
4 equals()和hashcode的关系
- 先通过hashcode比较,如果hascode相等,就用equals()来比较两个对象的内容是否相等;
- 如果两个对象equals()为true,那么这两个对象的hashcode一定相等;
- 如果两个对象的hashcode相等,不代表两个对象equals()为true,只能说明这两个对象在散列存储结构中,存放于同一个位置。
5 为什么equals()重写的话,建议也一起重写hashcode方法?
首先要保证一个原则,两对象如果equlas出来的结果相等,那么hashCode也一定相等。
如果有一个类重写了equals方法,但没有重写hashcode方法,那么当类的两个对象使用equals()比较时相等,但两者的hashcode不一样相等,这就导致了错误。
例如:
User u1 = new User(“张三”);
User u2 = new User(“张三”);
如果User类重写了equals()方法,使得 u1.equals(u2)返回true ;但是User类没有重写hashCode方法,它用的是Object类的hashCode方法,所以 u1.hashCode = 31050006 u2.hashCode = 31587890,两者的hashCode并不相等。