HashMap 中的扰动函数有没有必要

2019-07-25 16:36:36 +08:00
 jie170601

无意中看到 HashMap 的源码,
有个函数理解不了用途,
搜索引擎搜索了一下,
发现叫扰动函数:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

代码比较好看懂,
就是把高 16 位的信息加到低 16 位上来,
但是这样真的能降低 hash 的碰撞率吗?
按理说把[-2147483648,2147483647]缩到了[0,15],
假如数据分布均匀,
碰撞率应该是一定的呀?

4228 次点击
所在节点    Java
7 条回复
morethansean
2019-07-25 16:54:30 +08:00
你不是说你看了源码? index 是 hash 值和长度做与操作出来的啊...长度一般比较小基本就是低位掩码了,所以把高位信息混进来鸭。
x7395759
2019-07-25 17:30:24 +08:00
你两种都跑一下不就知道了
qwerthhusn
2019-07-25 17:35:16 +08:00
当然了,当桶数为 16 的时候,
决定落到那个桶是由初始 hash 值的最后 4 位决定的
扰一下,决定落到哪个桶是由初始 hash 值的最后 4 位和第 13-16 位总共 8 位决定的
qwerthhusn
2019-07-25 17:38:20 +08:00
虽然,全集合[-2147483648,2147483647]缩到了[0,15]是均匀的。
但是随机少量数据,通过 4 位和通过 8 位的分散概率肯定不一样。
jie170601
2019-07-26 07:51:14 +08:00
@qwerthhusn 是的随机少量的影响还是挺大的,可能数学专业惯性思维了,概率算的整个区间的🙃
jie170601
2019-07-26 07:52:55 +08:00
@x7395759 有人跑过了说能减少 10%的碰撞,但是这个和用的啥样本数据关系很大,不是很值得参考
deadlyn
2019-07-26 11:30:45 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/586184

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX