HashMap 的工作原理及代码实现,什么时候用到红黑树
HashMap工作原理及什么时候用到的红黑树:
在jdk 1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
在jdk 1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
原理:数组中的每一个元素所在的位置相当于一个位桶,添加元素的时候,首先计算元素key的hash值,确定插入数组中的位置(也就是哪个桶中),如果存在相同的hash值,则放在同一个桶中(元素位置)形成链表,当链表长度超过阈值(8)时,将链表转换为红黑树;
HashMap的内部结构:
HashMap 底层是基于数组和链表实现的,如图所示,其中两个重要的参数:容量和负载因子;容量的默认大小是 16,负载因子是 0.75,当 HashMap
的 size > 16*0.75
时就会发生扩容(容量和负载因子都可以自由调整)
内部包含了一个Node类型的数组 table(Entry<K,V>[] table为jdk 1.7中)。
transient Node<K,V>[] table;
Node存储着键值对。它包含了四个字段,从 next 字段我们可以看出Node是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值相同的Node;
拉链法的工作原理(解决hash冲突):
新建一个 HashMap,默认大小为 16;
- 插入 <K1,V1> 键值对,先计算 K1 的 hashCode 为 115,使用除留余数法得到所在的桶下标 115%16=3。
- 插入 <K2,V2> 键值对,先计算 K2 的 hashCode 为 118,使用除留余数法得到所在的桶下标 118%16=6。
- 插入 <K3,V3> 键值对,先计算 K3 的 hashCode 为 118,使用除留余数法得到所在的桶下标 118%16=6,插在 <K2,V2> 前面。
- 应该注意到链表的插入是以头插法方式进行的,例如上面的 <K3,V3> 不是插在 <K2,V2> 后面,而是插入在链表头部;
查找需要分成两步进行:
- 计算键值对所在的桶;
- 在链表上顺序查找,时间复杂度显然和链表的长度成正比;
HashMap 允许插入键为 null 的键值对。但是因为无法调用 null 的 hashCode() 方法,也就无法确定该键值对的桶下标,只能通过强制指定一个桶下标来存放。HashMap 使用第 0 个桶存放键为 null 的键值对。
注意:
在并发环境下使用
HashMap
容易出现死循环。并发场景发生扩容,调用
resize()
方法里的rehash()
时,容易出现环形链表。这样当获取一个不存在的key
时,计算出的index
正好是环形链表的下标时就会出现死循环。
HashMap 的工作原理及代码实现,什么时候用到红黑树的更多相关文章
- HashMap的工作原理以及代码实现,为什么要转换成红黑树?
原理参考:https://blog.csdn.net/striveb/article/details/84657326 总结: 为什么当桶中键值对数量大于8才转换成红黑树,数量小于6才转换成链表? 参 ...
- 从头认识java-15.7 Map(6)-介绍HashMap的工作原理-装载因子与性能
这一章节我们通过讨论装载因子与性能,再来介绍HashMap的工作原理. 1.什么是装载因子?他有什么作用? 以下的代码就是装载因子 /** * The load factor used when no ...
- 从头认识java-15.7 Map(4)-介绍HashMap的工作原理-hash碰撞(常常作为面试题)
这一章节我们来讨论一下hash碰撞. 1.什么是hash碰撞? 就是两个对象的key的hashcode是一样的,这个时候怎么get他的value呢? 答案是通过equals遍历table那个位置上面的 ...
- jdk1.8 ConcurrentHashMap 的工作原理及代码实现,如何统计所有的元素个数
ConcurrentHashMap 的工作原理及代码实现: 相比于1.7版本,它做了两个改进 1.取消了segment分段设计,直接使用Node数组来保存数据,并且采用Node数组元素作为锁来实现每一 ...
- HashMap的工作原理
HashMap的工作原理 HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...
- HashMap的工作原理深入再深入
前言 首先再次强调hashcode (==)和equals的真正含义(我记得以前有人会说,equals是判断对象内容,hashcode是判断是否相等之类): equals:是否同一个对象实例.注意,是 ...
- [转] HashMap的工作原理
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
- 【转】HashMap的工作原理
很好的文章,推荐Java的一个好网站:ImportNew HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hasht ...
- 转:HashMap的工作原理,及笔记
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
随机推荐
- PHP 中文字符串截取
$str = "abcdef啊啊吧啊"; function my_sub($str, $st ,$len){ $ret = ""; for( $st; $len ...
- 深入学习Make命令和Makefile(下)
https://www.zybuluo.com/lishuhuakai/note/209300 make是Linux下的一款程序自动维护工具,配合makefile的使用,就能够根据程序中模块的修改情况 ...
- [转]F5负载均衡名词LTM和GTM
LTM就是本地流量管理,也就是通常所说的服务器负载均衡.可以将多个提供相同服务的设备(pool)虚拟成一个逻辑设备,供用户访问.也就是说,对于用 户来讲,看到的只有一个设备,而实际上用户是服务请求是在 ...
- Doxygen生成C++中文文档配置注意事项
打开对应的Doxyfile,修改如下: 1.OUTPUT_LANGUAGE = Chinese. 2.INPUT_ENCODING = GB2312.
- docker报错“net/http: TLS handshake timeout”的解决方法
为了永久性保留更改,您可以修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值. { "registry-mirrors": ...
- 【读书笔记】socket函数
socket函数 简介 应用程序调用socket函数来创建一个能够进行网络通信的套接字. 1 2 3 4 5 /* 头文件 */ #include <sys/types.h> #inclu ...
- Android服务开发——WebService
我在学习Android开发过程中遇到的第一个疑问就是Android客户端是怎么跟服务器数据库进行交互的呢?这个问题是我当初初次接触Android时所困扰我的一个很大的问题,直到几年前的一天,我突然想到 ...
- Linux下openoffice与SWFtools的安装
第一部份:OpenOffice的安装 1.Openoffice的官网:http://www.openoffice.org/download/index.html 选择Linux 64-bit(x860 ...
- 【CF708E】Student's Camp 组合数+动态规划
[CF708E]Student's Camp 题意:有一个n*m的网格,每一秒钟,所有左面没有格子的格子会有p的概率消失,右面没有格子的格子也会有p的概率消失,问你t秒钟后,整个网格的上边界和下边界仍 ...
- CentOS安装php及其扩展
列出所有的可安装的软件包 yum list | grep php56w* | grep redis 安装php及其扩展 yum install -y php56w php56w-mysql php5 ...