Map接口:
map接口,是一种键值对的式的结构,开发中,经常使用这种结构
Map的常见实现类:
HashMap
Hashtable
ConcurrentHashMap
HashMap源码解析:
它是一个标准的哈希表
JDK8之前,HashMap:整体结构是一个"数组 + 链表" 结构
JDK8之后,HashMap:整体结构是一个"数组 + 链表 + 红黑树" 结构
哈希冲突:
什么是哈希冲突
哈希冲突的四种解决方案:
1、再哈希法
2、开放定址法
3、拉链法
4、公共的缓冲区
HashMap的结构及源码解析:
1、HashMap结构
JDK7及其以前版本,HashMap:整体结构是一个"数组 + 链表" 结构
JDK8之后,HashMap:整体结构是一个"数组 + 链表 + 红黑树" 结构,
目的链表的查询
2、什么时候链表转换为红黑树:
当链表长度大于8,同时数组长度大于64时,将从链表转换为红黑树
当链表长度小于6时,如果该链表之前是红黑树,则重新还原为链表结构
3、HashMap默认数组的容量是16,每次扩容必须保证为2的幂次方倍。
准确来说,是原有容量的2倍。
4、HashMap默认的负载因子是0.75,是因为泊松分布。
5、构造HashMap:
如果在构造时,所有参数默认,则容量是16,负载因子是0.75
如果在构造是,自己传递参数,容量必须保证为2的幂次方倍
6、put方法解析(如何添加元素)
1、首先会将key进行hash运算,如果为null,则hash值为0,否则
返回key的hashcode()的值(注意:该值会进行高低位异或运算)
目的是key的高低位二进制数据都参与到运算中来,是的key的
hash值足够散列(不要让key都插入到一个节点中)
2、添加节点:
如果数组没有初始化同时长度为0
如果是第一次添加节点,则容量是16,负载因子是0.75,触发扩容的阈值:12。
3、插入时,求插入key的下标
获取hashcode值,求模元素
(hash % length <===> (length - 1) & hash )
4、
ConcurrentHashMap:
jdk5诞生了并发的HashMap,采用的分段加锁的方式,所以效率被Hashtable 高至少16倍
如果出现高并发场景,建议使用ConcurrentHashMap;
ConcurrentHashMap在jdk8做了一次优化,加锁方式进行优化
引入了偏向锁(无锁)和自旋锁。