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进制的计算方式去计算。
-------------------------------------------------------------------------------------------
大家都知道,计算机的乘法涉及到移位计算。当一个数乘以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的秘密的更多相关文章
- “==”、“equals()”、“hashcode()”之间的秘密
前言 万丈高楼平地起,今天的聊点基础而又经常让人忽视的话题,比如“==”与“equals()”区别?为何当我们重写完"equals()"后也要有必要去重写"hashcod ...
- Java 8函数式接口functional interface的秘密
Java 8函数式接口functional interface的秘密 2014年10月29日 17:52:55 西瓜可乐520 阅读数:3729 目录 [−] JDK 8之前已有的函数式接口 新定 ...
- HashMap之equals和hashCode小陷阱
先以一段代码开始这篇blog. 01 public class Name { 02 03 private String first; //first name 04 private Str ...
- Java中HashCode()和equals()的作用
引言 我们知道Java中的集合(Collection)大致可以分为两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 这里就引出一个问题: ...
- TypeScript: Angular 2 的秘密武器(译)
本文整理自Dan Wahlin在ng-conf上的talk.原视频地址: https://www.youtube.com/watch?v=e3djIqAGqZo 开场白 开场白主要分为三部分: 感谢了 ...
- [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密
string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...
- 网站的SEO以及它和站长工具的之间秘密
博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...
- Java Map hashCode深究
[Java心得总结七]Java容器下——Map 在自己总结的这篇文章中有提到hashCode,但是没有细究,今天细究整理一下hashCode相关问题 1.hashCode与equals 首先我们都知道 ...
- 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 ...
随机推荐
- 给你一个 5L 和 3L 桶,水无限多,怎么到出 4L。
智力题 给你一个 5L 和 3L 桶,水无限多,怎么到出 4L. 思考过程 先将 3L 的桶装满水,倒入 5L 的桶里. 再重新将 3L 的桶装满水,倒入 5L 的桶里,把 5 L 的桶装满后,这样 ...
- oracle 子查询和组合函数
oracle 子查询和组合函数 --查询与"SCOTT"在同一个部门的员工 select empno,ename,deptno from emp where deptno in ( ...
- Vibrator震动
今天又学一招: Android手机中的震动由Vibrator实现.设置震动事件,需要知道其震动的时间长短.震动的周期等. 在 Android Vibrator中,震动的时间以毫秒计算(1/1000秒) ...
- cvc-complex-type.2.4.d: 发现了以元素 'd:skin' 开头的无效内容。此处不应含有子元素。
Eclipse上开发Android的时候,新建的项目提示: [2016-01-13 14:07:56 - android SDK] Error when loading the SDK: Erro ...
- 转:xxe attack学习
小结 1.http包发送类型:content-type:text/xml2.xxe漏洞非常危险, 因为此漏洞会造成服务器上敏感数据的泄露,和潜在的服务器拒绝服务攻击.要去校验DTD(document ...
- .htaccess文件
前言 看了几篇文章,发现自己对于如何维护普通的服务器安全完全不会,先从简单的.htaccess来研究吧 .htaccess文件的作用,就是更改httpd.ini文件中的配置,但作用范围仅限当前文件夹 ...
- python log的处理方式
python log的处理方式 配置文件 #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "Q1mi" ...
- 初拾Java(问题一:404错误,页面找不到)
做测试尤其是想走自动化测试之路的人,怎么可以不会码代码?!怒了... 再次开始拾起Java,坚持坚持!!! 刚写了一个JSP页面,想在Myeclipse里面跑来试试,结果搞了半天出现以下错误: 试着去 ...
- Failed to resolve directive: el vue2报错
vue2报错 Failed to resolve directive: el 为什么会报这个错呢,主要还是因为vue升级的时候,v-el在vue2.x以后被淘汰.使用新的标签ref替换v-el,接下来 ...
- 安卓 自定义ViewGroup
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 指定的 布局参数 在计算时候方法 中 计算 所有 子视图的 宽高, 然后根据这些 计算出 ...