看String源码HashCode的计算方式:
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进制的计算方式去计算。
-------------------------------------------------------------------------------------------
我们会注意那个狗血的31这个系数为什么总是在里面乘来乘去?为什么不适用32或者其他数字?

大家都知道,计算机的乘法涉及到移位计算。当一个数乘以2时,就直接拿该数左移一位即可!选择31原因是因为31是一个素数!

所谓素数:

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。

在存储数据计算hash地址的时候,我们希望尽量减少有同样的hash地址,所谓“冲突”。如果使用相同hash地址的数据过多,那么这些数据所组成的hash链就更长,从而降低了查询效率!所以在选择系数的时候要选择尽量长(31 = 11111[2])的系数并且让乘法尽量不要溢出(如果选择大于11111的数,很容易溢出)的系数,因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。

31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化,使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits!

在java乘法中如果数字相乘过大会导致溢出的问题,从而导致数据的丢失.

而31则是素数(质数)而且不是很长的数字,最终它被选择为相乘的系数的原因不过与此!

如i*31==(i<<5)-1  用二进制表示就是:
1<<5  移位 位100000
11111==100000-1 

HashCode的秘密的更多相关文章

  1. “==”、“equals()”、“hashcode()”之间的秘密

    前言 万丈高楼平地起,今天的聊点基础而又经常让人忽视的话题,比如“==”与“equals()”区别?为何当我们重写完"equals()"后也要有必要去重写"hashcod ...

  2. Java 8函数式接口functional interface的秘密

    Java 8函数式接口functional interface的秘密 2014年10月29日 17:52:55 西瓜可乐520 阅读数:3729   目录 [−] JDK 8之前已有的函数式接口 新定 ...

  3. HashMap之equals和hashCode小陷阱

    先以一段代码开始这篇blog. 01 public class Name { 02   03   private String first; //first name 04   private Str ...

  4. Java中HashCode()和equals()的作用

    引言 我们知道Java中的集合(Collection)大致可以分为两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 这里就引出一个问题: ...

  5. TypeScript: Angular 2 的秘密武器(译)

    本文整理自Dan Wahlin在ng-conf上的talk.原视频地址: https://www.youtube.com/watch?v=e3djIqAGqZo 开场白 开场白主要分为三部分: 感谢了 ...

  6. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密

    string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...

  7. 网站的SEO以及它和站长工具的之间秘密

    博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...

  8. Java Map hashCode深究

    [Java心得总结七]Java容器下——Map 在自己总结的这篇文章中有提到hashCode,但是没有细究,今天细究整理一下hashCode相关问题 1.hashCode与equals 首先我们都知道 ...

  9. How to implement equals() and hashCode() methods in Java[reproduced]

    Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...

随机推荐

  1. 简单的oracle sql语句练习

    简单的oracle sql语句练习 求每个部门的平均薪水 select deptno,avg(sal) from emp group by deptno 每个部门同一个职位的最大工资 select d ...

  2. 那些年遇到的php之坑

    1. php指针没有重置 $arr = array( array('aaaaaaaa'), array('bbbbbbb') ); unset($arr[0]); unset($arr[1]); so ...

  3. 不通过注册表使用ActiveX对象

    为了弄清楚COM库的运行原理,特意做了这个实验: #include "stdafx.h" #include "objbase.h" #include " ...

  4. vue v-model 简单使用

    最近在写组件时,考虑到子组件的状态需要实时反馈给父组件,于是想起来了v-model,下面介绍一下自定义组件中的简单使用 官网介绍不是很清晰,这个默认的input事件很容易让人产生误解,其实个人建议还是 ...

  5. 关于 Unity 的一些小细节,不注意可能会被“坑”一些时间。

    关于 Unity 的一些小细节,不注意可能会被"坑"一些时间. 最近因为一些"小"问题,总是需要找很久的原因,总结一下 UnityEngine.Input 在使 ...

  6. POJ1716 贪心

    题目大意:在[0,10000]上给出n个区间,要求在区间选整数点,每个区间至少包含两个点,问至少要几个点.题目保证有解决方案. 题目分析: 我们做过在区间上至少包含一个点的题目.类似的方法,我们先排序 ...

  7. [HAOI2012]外星人

    题目大意: 告诉你一个数n,求满足φ^x(n)=1的x. 思路: 首先我们可以发现满足φ(n)=1的数只有2,也就是说你得到最终的结果,最后一步肯定是φ(2). 同时,可以发现φ(φ(2^k))=φ( ...

  8. 在Ubuntu下编译hadoop2.5.x

    在Ubuntu下编译hadoop2.5.x 参考博客:http://www.aboutyun.com/thread-8130-1-1.html 1 下载hadoop源码: (1) http://www ...

  9. poj 1703 并查集

    题意:在这个城市里有两个黑帮团伙,现在给出N个人,问任意两个人他们是否在同一个团伙 输入D x y代表x于y不在一个团伙里 输入A x y要输出x与y是否在同一团伙或者不确定他们在同一个团伙里 链接: ...

  10. [bzoj1021][SHOI2008]Debt 循环的债务 (动态规划)

    Description Alice. Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他 们决定要在清还债 ...