HashCode详解
Posted Cookie-a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashCode详解相关的知识,希望对你有一定的参考价值。
(1)Hash表
hash是一个函数,该函数中的实现就是一种算法,就是通过一系列的算法来得到一个hash值,这个时候,我们就需要知道另一个东西,hash表,通过hash算法得到的hash值就在这张hash表中,也就是说,hash表就是所有的hash值组成的,有很多种hash函数,也就代表着有很多种算法得到hash值,
(2)HashCode
hashcode就是通过hash函数得来的,通俗的说,就是通过某一种算法得到的,hashcode就是在hash表中有对应的位置。
hashCode比较的是哈希码,哈希码是由特定的哈希算法的出。
一个对象肯定有物理地址,也有人把hashcode说成是代表对象的地址,这里肯定会让读者形成误区,对象的物理地址跟这个hashcode地址不一样,hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址 。 通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode 。
举个例子,hash表中有 hashcode为1、hashcode为2、(...)3、4、5、6、7、8这样八个位置,有一个对象A,A的物理地址转换为一个整数17(这是假如),就通过直接取余算法,17%8=1,那么A的hashcode就为1,且A就在hash表中1的位置。
(3) equals方法和hashcode的关系?
1、如果两个对象equals相等,那么这两个对象的HashCode一定也相同
2、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,
存放于同一个位置。hashCode()只表示对象的哈希码,哈希码相同的对象不一定相等,反之,没有重写equals方法的前提下,两个对象相等,则hashCode一定相同
(4)为什么equals方法重写的话,建议也一起重写hashcode方法?
(如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写)
举个例子,其实就明白了这个道理,
比如:有个A类重写了equals方法,但是没有重写hashCode方法,看输出结果,对象a1和对象a2使用equals方法相等,按照上面的hashcode的用法,那么他们两个的hashcode肯定相等,但是这里由于没重写hashcode方法,他们两个hashcode并不一样,所以,我们在重写了equals方法后,尽量也重写了hashcode方法,通过一定的算法,使他们在equals相等时,也会有相同的hashcode值。
equals()方法
hashCode()方法
HashCode()函数详解
Interger
public static int hashCode(int value) {
return value;
}
Interger类型数据的hashcode仅仅是返回其原有的值
Double
public static int hashCode(double value) {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
bits是双精度规格化浮点数的二进制
Double类的数据的hashcode是返回bits右移32位然后与bits相异或的结果
浮点数的表示
最高位是符号位(0为正,1为负)
其后的11位是阶码位以2为底,用移码表示,移码的偏置量是2^(11-1)-1=1023,
后52位是尾数的数值位。
例:浮点数是9.0
写成二进制则为1001,也可写成1.001×2^3.
符号位为0
浮点数的阶码为3+1023=1026=10000000010
数值位默认删除第一位整数位的1,只保留小数点后的数。为00100000补够后面的零
所以9.0的表示就是
0
10000000010
0010000000000000000000000000000000000000000000000000
异或
当两个数不同时为1,相同时为0
0∧0=0,0∧1=1,1∧1=0,1∧0=1
String
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h;
byte[] value传过来的是String每一个字符转成ascii码后的数组.
至于为什么选择31作为乘子,可以看 这篇文章
以上是关于HashCode详解的主要内容,如果未能解决你的问题,请参考以下文章