public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
若是String value="abcd"; 那么其计算结果为:
value[0]=a;
h=31*0+a; --31*0+97
=a; --97
value[1]=b;
h=31*(31*0+a)+b; --31*97+98
=31*a+b; --3007+98=3105
value[2]=31*(31*a+b)+c; --96255+99
=31*31*a+31*b+c; --96354
value[3]=31*(31*31*a+31*b+c)+d --31*96354+100
=31*31*31*a+31*31*b+31*c+d --2986974+100
h=31^(n-1)*value[0]+31^(n-2)*value[1]+31^(n-3)*value[2]+value[n-1];
进制转换的表示方法为:16进制的20表示成10进制就是:2×16¹+0×16º=32
那么HashCode的计算方式就是字符的ascii码 按照31进制的计算方式去计算。
-------------------------------------------------------------------------------------------
你们都知道,计算机的乘法涉及到移位计算。当一个数乘以2时,就直接拿该数左移一位便可!选择31缘由是由于31是一个素数!java
所谓素数:优化
质数又称素数。指在一个大于1的天然数中,除了1和此整数自身外,无法被其余天然数整除的数。spa
在存储数据计算hash地址的时候,咱们但愿尽可能减小有一样的hash地址,所谓“冲突”。若是使用相同hash地址的数据过多,那么这些数据所组成的hash链就更长,从而下降了查询效率!因此在选择系数的时候要选择尽可能长(31 = 11111[2])的系数而且让乘法尽可能不要溢出(若是选择大于11111的数,很容易溢出)的系数,由于若是计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提升。ci
31能够 由i*31== (i<<5)-1来表示,如今不少虚拟机里面都有作相关优化,使用31的缘由多是为了更好的分配hash地址,而且31只占用5bits!源码
在java乘法中若是数字相乘过大会致使溢出的问题,从而致使数据的丢失.虚拟机
而31则是素数(质数)并且不是很长的数字,最终它被选择为相乘的系数的缘由不过与此!hash
如i*31==(i<<5)-1 用二进制表示就是:
1<<5 移位 位100000
11111==100000-1