Skip to content

Commit d85b8fe

Browse files
authored
修改:“HashMap 的长度为什么是2的幂次方”
1 parent 29666cc commit d85b8fe

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

Java相关/这几道Java集合框架面试题几乎必问.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Arraylist不是同步的,所以在不需要保证线程安全时时建议使
3939

4040
### JDK1.8之前
4141

42-
JDK1.8 之前 HashMap 底层是 **数组和链表** 结合在一起使用也就是 **链表散列****HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,hash 值相同时,通过拉链法解决冲突**
42+
JDK1.8 之前 HashMap 底层是 **数组和链表** 结合在一起使用也就是 **链表散列****HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 `(n - 1) & hash` 判断当前元素存放的位置(这里的 n 指的时数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突**
4343

4444
**所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。**
4545

@@ -99,7 +99,7 @@ static int hash(int h) {
9999

100100
## HashMap 的长度为什么是2的幂次方
101101

102-
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法
102+
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648到2147483648,前后加起来大概40亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个40亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“ `(n - 1) & hash` ”。(n代表数组长度)。这也就解释了 HashMap 的长度为什么是2的幂次方
103103

104104
**这个算法应该如何设计呢?**
105105

0 commit comments

Comments
 (0)