什么是HashMap容器
【1】HashMap是使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。
【2】jdk1.8 之前 HashMap 由 数组 + 链表 组成,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突(两个对象调用的 hashCode 方法计算的哈希值经哈希函数算出来的地址被别的元素占用)而存在的(”拉链法”解决冲突)。jdk1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(或者红黑树的边界值,默认为 8 )并且当前数组的长度大于 64 时,此时此索引位置上的所有数据改为使用红黑树存储。
【3】HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
HashMap的疑难问题
【1】为什么转成树结构的阈值是8,而由树转回为链表结构的阈值是6?
在源码中有这么一段注释:
【2】为什么HashMap要保证数组长度是2的倍数呢?
源码分析HashMap的实现(我这里是拿JDK14的源码展示的)
【0】继承关系
【1】节点的类型分析
【2】属性值
【3】构造方法
【4】核心方法分析
【4.1】添加方法put()分析
【4.1.1】链表转成树结构treeifyBin()方法分析
【4.2】扩容方法resize()分析
【4.2.1】分析树节点的分割子树流程
【4.2.1.1】分析树节点的退化流程
【4.2.1.2】分析树节点的再次树化treeify()方法流程
【4.2.1.2】分析树节点的再平衡balanceInsertion()方法流程
【4.3】主体的存放逻辑已经阐述完了,下次有空再补一下JDK7的版本吧,毕竟JDK8可是修复了老版本的大BUG。
Original: https://www.cnblogs.com/chafry/p/16826517.html
Author: 忧愁的chafry
Title: HashMap详解
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/712478/
转载文章受原作者版权保护。转载请注明原作者出处!