当前位置: 首页 > 面试题库 >

更改为Java 8中的HashMap哈希函数

谈炳
2023-03-14
问题内容

在Java 8
java.util.Hashmap中,我注意到来自的更改:

static int hash(int h) {
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);

至:

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

从代码中可以看出,新功能是XOR低16位的简单形式,而高16位则保持了高16位不变,这与先前实现中的几种不同移位相反,并且从注释中可以看出,这在分配上不太有效散列函数的结果,其中低位对不同的存储区具有大量冲突,但由于必须执行较少的操作,因此节省了CPU周期。

我在发行说明中唯一看到的是从链接列表到平衡树的更改,以存储碰撞键(我认为这可能已经改变了计算一个好的哈希值所花费的时间),我特别感兴趣此更改对大型哈希图是否有预期的性能影响。是否有关于此更改的任何信息,还是对哈希函数有更好了解的人是否知道此更改的含义(如果有的话,也许我只是误解了代码)以及是否需要生成哈希迁移到Java
8时以不同的方式维护性能的代码?


问题答案:

如您所述:HashMap如JEP-180中所述,Java
8中的性能有了显着提高。基本上,如果哈希链超过一定大小,HashMap则将(如果可能)将其替换为平衡的二叉树。这将导致各种操作的“最坏情况”行为,O(log N)而不是O(N)

这并不能直接说明对的更改hash。但是,我 假设
JEP-180中的优化意味着散列函数分布不均对性能造成的影响不那么重要,并且该方法的成本效益分析hash有所变化。即,较复杂的版本 平均而言
受益较少。(束缚地说,当密钥类型的hashcode方法生成高质量的代码时,那么复杂hash方法中的体操将浪费时间。)

但这只是一个理论。进行hash更改的真正理由很可能是Oracle机密。



 类似资料:
  • 我想重定向到另一个页面 这工作正常,但它首先会变为 我也试着跟随 它正在创建一个正确的URL,但没有向下滚动到id为某个DIV id的 编辑 另外我尝试了

  • 1. HashMap概述 HashMap是基于哈希表的Map接口的非同步实现(Hashtable跟HashMap很像,唯一的区别是Hashtalbe中的方法是线程安全的,也就是同步的)。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 2. 四个关注点在HashMap上的答案 关注点 结论 HashMap是否允许空 Key和Val

  • 问题内容: 我只是在阅读有关Java中HashMap和HashTable类之间的区别。在那里,我发现了一个区别,即前者允许空键,而后者则没有特权。就HashMap的工作而言,我知道,它在键上调用hashcode方法,以查找要在其中放置该键值对的存储桶。我的问题来了:如何计算空值的哈希码?或者空键的哈希码是否有任何默认值(如果需要,请指定该值)? 问题答案: 从HashMap: 如果进一步看,您会发

  • 我正在寻找一种通过改变散列来改变部分样式的方法。让我以一个例子来解释: > 当前URL为: 然后单击复选框,URL将更改为: 我想更改类的。 我尝试了以下代码,但它不起作用: 实际上,每次哈希更改时,控制台中都不会出现任何内容。

  • 可能重复: HashMap#hash(int)方法的解释 有人能详细解释一下这个方法吗,谢谢。

  • HashMap将其数据保存在存储桶中,如下所示: 要在HashMap中放置一些东西,我们需要一个hash()函数,它返回从0到table.length()范围内的关键哈希,对吗? 假设我有: 这将返回以下内容: 字符串本机哈希代码:46882035,哈希映射哈希:46882360 我们应该有大约256个桶(所以关键的散列应该在0到256的范围内),但是HashMap中的内部散列给了我们468823