Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d85b8fe

Browse files
修改:"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‎

Lines changed: 2 additions & 2 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /