HashMap的元素hash散列均匀必要性及算法优化
来源:互联网 发布:网络教研实施方案 编辑:程序博客网 时间:2024/06/15 17:03
之前看过HashMap的一些东西,时间一久就容易忘,而已一些要点理解得不深入,今天看到这篇文章很不错,具有相同hashcode(称为hash冲突)的对象会放在同一下标的数组元素中,如果冲突的元素多,那么同一链表的长度就会越来越长,这样在遍历的时候就费时,所以就要让存进来的对象相对均匀地放入在所有的链表中。
通过源码可以知道,indexFor(hash, table.length)方法用来计算数组下标的值,hash为对象经过计算后的hash值,具体算法:hash & (length-1),hash与上数组长度-1,等同于hash mod length,只是在计算机中做二进制位运算效率最高。在Entry数组长度不是很大时只会对低位进行与运算操作,高位值不参与运算(如果Entry大小为32,则只会与低5位进行与操作),很容易发生hash冲突,具体经过请见下面。这就是为什么要散列得更地均衡,怎么保证散列更加均匀的原因。
HashMap是很重要的一个数据结构,一定要深入理解它。
转自hashCode相关性能优化
学习下hashMap中用到的关于hashCode性能优化技巧,作为笔记,为之后并发深入作基础。
1.关于提高性能的hash算法
在被模的位数为2的n次方时,用位与代替效率低下的模运算。位与效率相比模运算效率更高。例:15%4=3,代替为 15 & 3=1111 & 0011=0011=3
hashmap中在求得某个key后,需要找到在哪个Entry数组下标的运算如下:
static int indexFor(int h, int length) {
return h & (length-1);
}
例:
两个key,调用Object的hash方法后值分别为:
32,64,然后entry数组大小为:16,即在调用indexFor时参数分别为[32,15],[64,15],
这时分别对它们调用indexFor方法:
32计算过程:
100000 & 1111 => 000000 =>0
64计算过程如下:
1000000 & 1111 => 000000 =>0
可以看到indexFor在Entry数组大小不是很大时只会对低位进行与运算操作,高位值不参与运算(如果Entry大小为32,则只会与低5位进行与操作),很容易发生hash冲突。
这里,32与64这两个hash值,都被存储在Entry数组0的位置上。
为了解决这个问题,HashMap在做indexFor操作前,需要调用hash方法,使hash值的位值在高低位上尽量分布均匀,hash方法:
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
还是按前面的key,经过Object的hash方法后,分别为32,64来进行运算:
32调用hash运算过程如下:
原始h为32的二进制:
100000
h>>>20:
000000
h>>>12:
000000
接着运算 h^(h>>>20)^(h>>>12):
结果: 100000
然后运算: h^(h>>>7)^(h>>>4),
过程如下:
h>>>7: 000000
h>>>4: 000010
最后运算: h^(h>>>7)^(h>>>4),
结果: 100010,即十进制34
调用indexFor方法:
100010 & 1111 => 2,即存放在Entry数组下标2的位置上
------------------------------------
64的运算结果为:1000100,十进制值为68
调用indexfor方法:
1000100 & 1111 => 4,即存放在Entry数组下标4的位置上
可以看到经过hash方法后,再调用indexFor方法,这样可以减少冲突。
0 0
- HashMap的元素hash散列均匀必要性及算法优化
- Hashmap的hash算法
- Hash算法,及HashMap使用
- Java HashMap的hash算法
- [hash] -- 分布均匀的hash函数
- Hash散列算法解析
- hash算法 (hashmap 实现原理) Java实现的散列表
- hash算法 (hashmap 实现原理) Java实现的散列表
- jump Consistent hash:零内存消耗,均匀,快速,简洁,来自Google的一致性哈希算法
- HashMap的hash算法(解决hash冲突的方式)
- Hash散列算法之 Time33算法
- HashMap分析及散列的冲突处理
- HashMap分析及散列的冲突处理
- Hash表及hash算法的分析
- 内部元素一一对应的集合的算法优化,从list到hashmap
- URL散列算法-ELF Hash法
- 单向散列函数,HASH算法
- 散列(hash)表算法[转]
- NYOJ-325-zb的生日(典型搜索)
- 从零开始写shell脚本(3)-基本概念
- 安装系统·时要注意的一些东西
- Linux TCP相关配置项
- [Android 基础系列]Service、IntentService和习以为常的误解
- HashMap的元素hash散列均匀必要性及算法优化
- 深入理解 __doPostBack
- 数据库中限制重复插入
- log4j自定义不同日志文件及动态配置路径
- flex写的下载器在Google浏览器下有些文件下载不了如exe文件
- SEO搜索优化傻脸了:Google放弃PageRank
- 使用veil-evasion+metasploit生成基于python的后门软件
- Android 图片压缩技术
- js form表单发送数据两种方式(post get)区别