Java 8 中的 Hashmap 性能改进

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

问题:

在 Java 7 之前, java.util.Hashmap 实现总是遇到哈希冲突问题,即当多个 hashCode() 值最终出现在同一个桶中时,这些值将放在链表实现中,这会降低 Hashmap 的性能 O(1 ) 到 O(n)。

解决方案:

通过使用平衡树而不是链表来存储映射条目,提高 java.util.HashMap 在高散列冲突条件下的性能。这将提高实现 Comparable 任何键类型的冲突性能。

此 JDK 8 更改仅适用于 HashMap LinkedHashMap ConcurrentHashMap
主要思想是,一旦哈希桶中的项目数量增长超过某个阈值 ( TREEIFY_THRESHOLD ),该桶将从使用条目链表切换到平衡树。在高散列冲突的情况下,这会将最坏情况下的性能从 O(n) 提高到 O(log n),并且当它们变得太小时(由于删除或调整大小)它们将转换回链表。


 static final int TREEIFY_THRESHOLD = 8;

static final int UNTREEIFY_THRESHOLD = 6;

另请注意,在极少数情况下,此更改可能会导致 HashMap HashSet 的迭代顺序发生变化。没有为 HashMap 对象指定特定的迭代顺序——任何依赖于迭代顺序的代码都应该是固定的。