Java 8中HashMap冲突解决
目录(?)[+]
在Java 8 之前,HashMap和其他基于map的类都是通过链地址法解决冲突,它们使用单向链表来存储相同索引值的元素。在最坏的情况下,这种方式会将HashMap的get方法的性能从O(1)降低到O(n)。为了解决在频繁冲突时hashmap性能降低的问题,Java 8中使用平衡树来替代链表存储冲突的元素。这意味着我们可以将最坏情况下的性能从O(n)提高到O(logn)。
在Java 8中使用常量TREEIFY_THRESHOLD来控制是否切换到平衡树来存储。目前,这个常量值是8,这意味着当有超过8个元素的索引一样时,HashMap会使用树来存储它们。
这一改变是为了继续优化常用类。大家可能还记得在Java 7中为了优化常用类对ArrayList和HashMap采用了延迟加载的机制,在有元素加入之前不会分配内存,这会减少空的链表和HashMap占用的内存。
这一动态的特性使得HashMap一开始使用链表,并在冲突的元素数量超过指定值时用平衡二叉树替换链表。不过这一特性在所有基于hash table的类中并没有,例如Hashtable和WeakHashMap。
目前,只有ConcurrentHashMap,LinkedHashMap和HashMap会在频繁冲突的情况下使用平衡树。
什么时候会产生冲突
HashMap中调用hashCode()方法来计算hashCode。
由于在Java中两个不同的对象可能有一样的hashCode,所以不同的键可能有一样hashCode,从而导致冲突的产生。
总结
- HashMap在处理冲突时使用链表存储相同索引的元素。
- 从Java 8开始,HashMap,ConcurrentHashMap和LinkedHashMap在处理频繁冲突时将使用平衡树来代替链表,当同一hash桶中的元素数量超过特定的值便会由链表切换到平衡树,这会将get()方法的性能从O(n)提高到O(logn)。
- 当从链表切换到平衡树时,HashMap迭代的顺序将会改变。不过这并不会造成什么问题,因为HashMap并没有对迭代的顺序提供任何保证。
- 从Java 1中就存在的Hashtable类为了保证迭代顺序不变,即便在频繁冲突的情况下也不会使用平衡树。这一决定是为了不破坏某些较老的需要依赖于Hashtable迭代顺序的Java应用。
- 除了Hashtable之外,WeakHashMap和IdentityHashMap也不会在频繁冲突的情况下使用平衡树。
- 使用HashMap之所以会产生冲突是因为使用了键对象的hashCode()方法,而equals()和hashCode()方法不保证不同对象的hashCode是不同的。需要记住的是,相同对象的hashCode一定是相同的,但相同的hashCode不一定是相同的对象。
- 在HashTable和HashMap中,冲突的产生是由于不同对象的hashCode()方法返回了一样的值。
但是,当某种针对key的hashcode的哈希运算得到的位置信息重复了之后,就发生了哈希碰撞。这会对HashMap的性能产生灾难性的影响。
在Java 8 之前, 如果发生碰撞往往是将该value直接链接到该位置的其他所有value的末尾,即相互碰撞的所有value形成一个链表。
因此,在最坏情况下,HashMap的查找时间复杂度将退化到O(n).
但是在Java 8 中,该碰撞后的处理进行了改进。当一个位置所在的冲突过多时,存储的value将形成一个排序二叉树,排序依据为key的hashcode。
则,在最坏情况下,HashMap的查找时间复杂度将从O(1)退化到O(logn)。
虽然是一个小小的改进,但意义重大:
1、O(n)到O(logn)的时间开销。
2、如果恶意程序知道我们用的是Hash算法,则在纯链表情况下,它能够发送大量请求导致哈希碰撞,然后不停访问这些key导致HashMap忙于进行线性查找,最终陷入瘫痪,即形成了拒绝服务攻击(DoS)。
Java 8中HashMap冲突解决相关推荐
- Eclipse中Egit冲突解决
Eclipse中Egit冲突解决 Git 作为进来最流行的分布式版本控制软件来说应用的十分广泛.EGit就是一款Eclipse上的Git插件.在使用Egit提交项目时,有时会产生冲突,需要对代码进行m ...
- eclipse中svn冲突解决
最近在和同事做项目的时候出现了冲突,冲突解决方法是这样的: 右键项目 -> Team -> 与资源库同步 2.在同步视图中选择Conflicts Mode,以便首先查看解决冲突 3.双击需 ...
- Java 8 中 HashMap 到底有啥不同?
点击关注公众号,Java干货及时送达 作者:废物大师兄 来源:www.cnblogs.com/cjsblog/p/8207211.html JDK1.8中的HashMap实现跟JDK1.7中的实现有很 ...
- 团队开发中Git冲突解决
正常来说我们团队协作开发过程中,冲突是常有的事,下面介绍下本人在开发中的解决办法. 冲突的主要原因就是由于我们开发人员在分支的同一位置写入了不一样的代码,然后合并到主干上导致我们冲突. 方法: 当冲突 ...
- 项目管理过程中六种冲突解决方法
整理自信管网.希赛网以及网上摘录. 博客:https://www.zenwu.site/post/e1bc.html 冲突的解决方法,不管冲突对项目的影响是正面的还是负面的,项目经理都有责任处理它,以 ...
- git在idea中的冲突解决(非常重要)
1.什么是冲突 冲突是指当你在提交或者更新代码时被合并的文件与当前文件不一致.读起来有点绕,结合下面的案例理解. 从上面对冲突的定义来看,冲突时发生在同一个文件上的. 2.生产上冲突的场景 常见冲突的 ...
- .Net中DLL冲突解决(真假美猴王)
<西游记>中真假美猴王让人着实难以区分,但是我们熟知了其中的细节也不难把他们剥去表象分别出来.对问题不太关心的可以直接调到文中关于.Net文件版本的介绍 问题 最近在编译AKKA.net ...
- Java集合中HashMap日常问题及解决办法
2019独角兽企业重金招聘Python工程师标准>>> 前言 今天在学习Session的时候,利用了Session可持久化保存服务器端的特性尝试做了一下用HashMap嵌套的购物车( ...
- LINUX中SVN冲突解决办法
svn执行up更新后,有时会出现冲突,如果需要编辑冲突,可以选择(p)postpone 稍后处理,svn会自动生成三个冲突文件,xx.cpp.maine是你自己的修改版本,其他带编号的是别人的提交版本 ...
最新文章
- 090_块元素行内元素行内块元素空元素
- DOM基本操作(二:对节点的操作)
- 微软Azure开源开发者(深圳)峰会等你来
- Spring事件的观察者模式
- 集合添加元素python_Python基础:列表、字典、元组、集合、添加和删除元素,增删...
- 内网DNS地址自己定
- 深入理解JVM-类加载器深入解析(3)
- spring单例的bean是单例还是原型
- Elastic Search 学习笔记
- Linux命令行大小写转换
- 暴几个用明文在网上传输用户名密码的网站
- 东芝笔记本电脑重装系统
- 通过ssh远程启动linux上的Qt界面程序
- 删除二叉树节点完整c语言程序以及例子,C语言C++实现二叉树构造与查找删除节点.doc...
- 谭浩强版c语言笔记(1)
- Xilinx FPGA clk_wiz IP使用
- 使用antd-pro组件 实现图片上传和图片编辑
- 国信证券学习系列(5)
- 西门子博途v16系统要求_博途V16安装TIA Portal v16
- 企业微信+微信+简道云+API:创建贴心实用的学生请假系统(二)之技术方案
热门文章
- pandas 替换 某列大于_pandas数据分析总结大全(入门加进阶)
- spring gateway 限流持久化_Spring Cloud Gateway 扩展支持动态限流
- mysql断网_mysql数据库断网链接
- css hack *html,CSS Hack详解
- 机架搭建_铝型材设备机架定制流程
- 线刷一加5t android 9,一加5/5T 氢OS 9.0稳定四版 侧边工具 通知特效 Magisk 极速流畅 简约实用-刷机之家...
- c语言的文案,点心回顾 | 这是一个充满有趣灵魂的C语言乐园!
- linux 有线网卡,linux下有线网卡出现ADDRCONF(NETDEV_UP): eth0: link is not ready的解决方法...
- python open encoding为无效的参数_TypeError:“encoding”是无效的关键字参数ex23.py
- IntelliJ 平台 2020 年路线图