Java 8 中 HashMap 哈希函数的更改

2024-01-02

在 java 8 java.util.Hashmap 中我注意到一个变化from http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/HashMap.java#HashMap.hash%28int%29:

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

to http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/HashMap.java#HashMap.hash%28java.lang.Object%29:

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

从代码来看,新函数更加简单XOR将低 16 位与高 16 位混合,保持高 16 位不变,这与之前实现中的几个不同的移位相反,并且从评论来看,这在分配具有大量冲突的哈希函数的结果时效率较低。将较低位分配给不同的存储桶,但通过执行更少的操作来节省 CPU 周期。

我在发行说明中唯一看到的是change http://openjdk.java.net/jeps/180从链接列表到平衡树来存储冲突键(我认为这可能会改变计算良好哈希值所花费的时间),我特别感兴趣的是看看这种变化是否会对大型设备产生任何预期的性能影响哈希映射。是否有关于此更改的任何信息,或者对哈希函数有更好了解的人是否知道此更改可能会产生什么影响(如果有的话,也许我只是误解了代码)以及是否需要生成哈希迁移到 Java 8 时以不同的方式编写代码以保持性能?


正如您所指出的:性能显着提高HashMap在 Java 8 中,如所述JEP-180 http://openjdk.java.net/jeps/180。基本上,如果哈希链超过一定大小,HashMap将(在可能的情况下)用平衡二叉树替换它。这使得各种操作的“最坏情况”行为O(log N)代替O(N).

这并不能直接解释这一变化hash。不过,我愿意假设JEP-180 中的优化意味着由于分布不均的哈希函数而造成的性能影响不太重要,并且对hash方法改变;即越复杂的版本好处越少一般。 (请记住,当按键类型hashcode方法生成高质量的代码,然后在复杂版本中进行体操hash方法都是浪费时间。)

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 8 中 HashMap 哈希函数的更改 的相关文章

随机推荐

  • MySQL InnoDB 因等待表级锁而挂起

    我有一个大型生产网络应用程序 Glassfish 3 1 MySQL 5 5 所有表都是InnoDB 每隔几天应用程序就会完全挂起 SHOW FULL PROCESSLIST显示不同表上的许多简单插入或更新查询 但都有状态 等待表级锁 例子
  • 从 JSP 列表填充 JavaScript 数组

    好吧 也许有人可以帮助我解决我正在尝试解决的问题 本质上 我有一个 JSP 页面 它获取 Country 对象的列表 来自 Spring Portlet SimpleFormController 的方法 referenceData 不完全相
  • Spark 中的任务是什么? Spark Worker如何执行jar文件?

    阅读了一些文档后http spark apache org docs 0 8 0 cluster overview html http spark apache org docs 0 8 0 cluster overview html 我有
  • Spring 5 LDAP 身份验证和 JWT 令牌作为响应

    你好 我一直在尝试配置 spring 让它在用户 通行证通过 LDAP 服务器身份验证时返回 JWT 令牌 考虑下面的用例 在上图中 我已将 WebSecurity 配置为使用 Bearer 检查 过滤请求 请参阅下面的代码 WebSecu
  • 如何因数据绑定的 safeUnbox 警告而导致构建过程失败

    这个问题 https stackoverflow com questions 42872201 data binding safeunbox warning解释什么是 safeUnbox 警告 我的 build gradle 中有以下内容
  • 如何检测触摸事件是否已落在 EditText 内?

    我可以找到 getX 和 getY 都返回一个浮点数 但是如何检测 TouchEvent e get e getY 的坐标是否在 EditText UI 元素的边界内 我注意到 getX 和 getY 是浮点数 但 getHeight 和
  • 使用 Jquery Ajax 和 PHP 的 Google 隐形 Recaptcha

    试图让我的表单使用谷歌隐形验证码与我的 jQuery AJAX 和 PHP 一起正常工作 根据我的研究 令牌似乎没有通过 AJAX 正确发送到我的 PHP 页面 提交表单时 我的 PHP 页面不断收到以下错误 array 2 success
  • nginx 上的 Zend 框架

    我一直在开发的基于 Zend Framework 的站点现在正在迁移到其生产服务器 该服务器原来是 nginx 惊讶 当然 该站点无法正常工作 因为它是在 Apache 上开发的并且依赖于 htaccess 文件 我的问题是 有人有这方面的
  • Android Gallery 的 getView() 返回不正确的位置

    谢谢阅读 我使用 Android Gallery 并将两个 LayoutParams 都设置为 MATCH PARENT 来一次显示一张全屏图像 这是我的代码 布局 xml
  • 从 CSV 文件的字符串列中删除新行

    我有一个包含多个字段的 CSV 文件 很少有字段 字符串 的数据跨越多行 我想将这些多行聚合成一行 输入数据 1 asdsdsdsds John 2 dfdhifdkinf dfjdfgkdnjgknkdjgndkng dkfdkjfnjd
  • 如何修复 Bower ECMDERR

    我在 Windows 7 上使用 yeoman 和 bower 但在创建应用程序时出现以下错误 yo webapp 错误是 bower not cached git github com jlong sass bootstrap git 3
  • 正则表达式删除一个空格

    删除一个空格的正则表达式是什么 例如 H e l l o W o r l d gt Hello World 请注意 Hello World 之间仍然有一个空格 一开始它之间就有两个空格 仅供参考 我正在使用 C 正则表达式 以前我做过类似的
  • UILabel视图在高度大于8192时消失

    将大字符串分配给 UILabel 并且 将此标签添加到滚动视图中 当 UILabel 高度大于 8192pt 即 2 13 时 UILabel 消失 这是 iOS 的错误吗 我应该使用其他实现来渲染如此数量的字符串吗 我应该将表格视图与单元
  • 使用ActiveRecord实现Rails中的复杂关系

    From 另一个问题 https stackoverflow com questions 27342419 generate a rails model from within code invoke generator from a co
  • C 中的 MIN 和 MAX

    在哪MIN and MAX如果有的话 是在 C 中定义的吗 实现这些的最佳方法是什么 尽可能通用并安全地输入 首选主流编译器的编译器扩展 内置函数 在哪MIN and MAX如果有的话 是在 C 中定义的吗 他们不是 实现这些的最佳方法是什
  • 确定可执行文件(或库)是 32 位还是 64 位(在 Windows 上)

    我试图查明给定的可执行文件 或库 是否是从 Python 编译为 32 位或 64 位的 我正在运行 Vista 64 位 并且想确定目录中的某个应用程序是针对 32 位还是 64 位进行编译 有没有一种简单的方法可以仅使用标准 Pytho
  • 在 Swift 中智能搜索解析用户名不起作用

    我试图在我的 iOS 应用程序中进行智能搜索 以便当用户在 UISearchBar 中键入字符时 结果会自动在搜索栏下方的表格视图中更新 由于某种原因 当我在搜索栏中输入字符时 不会调用带有 textDidChange 的 searchBa
  • 评论缩进在 clojure 模式下似乎很混乱

    在 clojure 模式下 emacs 用 5 个选项卡缩进我的分号注释 即使它是空文件中的第一行也会发生这种情况 例如 只需打开一个 clojure 文件 输入 在第一个字符处并按 Tab 键 我使用的是1 7 1版本 这是正常行为 在您
  • Android:无法确保目录

    我一直在使用 Environment getExternalStorage 来存储和管理文件 并且没有任何警告消息logcat用这种方法并且效果很好 但是 我的项目需要使用方法 Context getExternalFilesDir Str
  • Java 8 中 HashMap 哈希函数的更改

    在 java 8 java util Hashmap 中我注意到一个变化from http grepcode com file repository grepcode com java root jdk openjdk 7 b147 jav