(1)首先明确一点,hashCode函数返回类型是int类型,也就是32位;
(2)生成hashCode原则,尽量让所有元素都参数运算,保证唯一性;
(3)不同类型的key,生成算法不一样;
Integer
把value当成hashCode返回;
public static int hashCode(int value) {
return value;
}
Short、Byte
直接把value转成int返回;
public static int hashCode(byte value) {
return (int)value;
}
Float
因为涉及到小数,所以把value转成二进制,然后转成该二进制对应的Integer值返回(说实在话源码,我没怎么看懂,哈哈);
public static int floatToIntBits(float value) {
int result = floatToRawIntBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & FloatConsts.EXP_BIT_MASK) ==
FloatConsts.EXP_BIT_MASK) &&
(result & FloatConsts.SIGNIF_BIT_MASK) != 0)
result = 0x7fc00000;
return result;
}
Long
因为Long是64位,而且为了让所有元素都参与运算,将value无符号右移32位,异或原来二进制数(可以理解为高32位于低32位做运算),转成Integer返回,高低 32位都参数运算可以减少冲突,只要其中一位发生变化就能马上感知,
public static int hashCode(long value) {
return (int)(value ^ (value >>> 32));
}
Double
因为Double涉及到小数,所以跟Float类型,先把value转成二进制,再转成对应的long,接下来就是Long类型的处理,无符号右移动32,做异或运算返回Integer值。
public static int hashCode(double value) {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
String
以"abcd"为例,公式为:a31^3+b312+c*311+d31^0,a、b、c、d分別表示字母在ASCII值。其实这个计算公式在参考整数的计算,1234=1103+2*102+310^1+410^0。
Tips:jdk采用31,因为31是奇素数,31*i会转换成位运算(i<<5)-i,运算比较快。
public int hashCode() {
int h = hash;
final int len = length();
if (h == 0 && len > 0) {
for (int i = 0; i < len; i++) {
h = 31 * h + charAt(i);
}
hash = h;
}
return h;
}
自定义对象
自定义对象的hashCode根据对象的内存地址生成的。
Tips:即使计算过程中有溢出也没有关系,因为我们只需要结果;
如果用与运算
//与运算后的返回结果就是原始数据的低32位,这相当于高32位没有参与运算,
所以与运算不合适。
public void test() {
/* 原始数据:11111111111111111111111111111111 10101010101010101010101010101010
无符号右移32位,高位补0:00000000000000000000000000000000 11111111111111111111111111111111
原始数据:11111111111111111111111111111111 10101010101010101010101010101010
与预算结果:00000000000000000000000000000000 10101010101010101010101010101010
*/
}
如果用或运算
//或运算返回结果就是原始数据的高32位,这相当于低32位没有参与运算,
所以或运算不合适。,
public void test() {
/* 原始数据:11111111111111111111111111111111 10101010101010101010101010101010
无符号右移32位,高位补0:00000000000000000000000000000000 11111111111111111111111111111111
原始数据:11111111111111111111111111111111 10101010101010101010101010101010
或算结果:11111111111111111111111111111111 11111111111111111111111111111111
返回结果: 11111111111111111111111111111111
*/
}
网友评论