深入理解HashMap,hash函数
来源:互联网 发布:js鼠标移入事件 编辑:程序博客网 时间:2024/04/30 11:07
粗浅的咱们不说,熟悉Java的应该都用过HashMap,实现原理就是应用散列实现键值对的映射。主要讨论下HashMap中的散列算法,首先看JDK源代码:
1
public
V put(K key, V value) {
2
if
(key ==
null
)
3
return
putForNullKey(value);
4
int
hash = hash(key.hashCode());
5
int
i = indexFor(hash, table.length);
6
for
(Entry e = table[i]; e !=
null
; e = e.next) {
7
Object k;
8
if
(e.hash == hash && ((k = e.key) == key || key.equals(k))) {
9
V oldValue = e.value;
10
e.value = value;
11
e.recordAccess(
this
);
12
return
oldValue;
13
}
14
}
15
16
modCount++;
17
addEntry(hash, key, value, i);
18
return
null
;
19
}
这是HashMap中的put方法。其中最重要的两句定位的话如下:
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
我们先从第一句开始分析,hash算法在HashMap中定义如下:
1
<span style=
"color: #000000;"
>
static
int
hash(
int
h) {
2
// This function ensures that hashCodes that differ only by
3
// constant multiples at each bit position have a bounded
4
// number of collisions (approximately 8 at default load factor).
5
h ^= (h >>>
20
) ^ (h >>>
12
);
6
return
h ^ (h >>>
7
) ^ (h >>>
4
);
7
}</span>
8
9
<span style=
"color: #000000;"
>
先复习下Java操作符:
“^”代表异或运算,11得1 00得1 10得0;
“&”代表与运算,11得1 00得0 10得0;
“>>>”是移位运算,把1和0按位移动;
假设key.hashCode()的值为:0x7FFFFFFF,table.length为默认值16。
上面算法执行如下:
得到i=15 。这种算法使得最低位上原hashCode的8位都参与了^运算,所以在table.length为默认值16的情况下面,hashCode任意位的变化基本都能反应到最终hash table 定位算法中,这种情况下只有原hashCode第3位高1位变化不会反应到结果中,即:0x7FFFF7FF的i=15。
这样做的好处是什么?我的理解是:它的目的是让“1”变的均匀一点,散列的本意就是要尽量均匀分。先看个例子,一个十进制数32768(二进制1000 0000 0000 0000),经过上述公式运算之后的结果是35080(二进制1000 1001 0000 1000)。看出来了吗?或许这样还看不出什么,再举个数字61440(二进制1111 0000 0000 0000),运算结果是65263(二进制1111 1110 1110 1111),现在应该很明显了。至于怎么证明这个运算确实可以散列均匀。。我目前还不知道,希望能有达人帮我解答。
那散列的均匀又有何用?来分析下一句话:
int i = indexFor(hash, table.length);
这个indexFor方法很简单:
1
/**
2
* Returns index for hash code h.
3
*/
4
static
int
indexFor(
int
h,
int
length) {
5
return
h & (length-
1
);
6
}
当计算出来的hash函数h和hashMap的length做了&运算后,会得到[0,length-1]其中的一个值,而散列的均匀也会使这个值分布的均匀,从而达到HashMap高效的一点。
- 深入理解HashMap,hash函数
- 深入理解 hash 函数、HashMap、LinkedHashMap、TreeMap
- 深入理解 hash 函数、HashMap、LinkedHashMap、TreeMap
- 深入理解 hash 函数、HashMap、LinkedHashMap、TreeMap 【上】
- 深入理解 hash 函数、HashMap、LinkedHashMap、TreeMap 【中】
- hash函数 hashMap的深入理解,jdk8 hashMap加入红黑树算法
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- 深入理解HashMap(及hash函数的真正巧妙之处)
- RMQ问题的ST算法读书笔记
- menudrawer
- ESB就是各种webservice的组装平台
- 编程之美3.4 从无头单链表中删除节点
- 远程桌面怎样复制本地文件
- 深入理解HashMap,hash函数
- Hash算法以及java hashmap的源码分析
- LINUX自旋锁详解
- 触摸屏是一个符合人体工程学的解决方案吗
- 多校联合第九场1001HDU4686 Arc of Dream
- IPTV支持TS流的方案形成过程
- 如何检测apache配置文件是语法是否正确
- URAL 1146
- 站内搜索