-
<李>
数据结构
1.8的版本的HashMap采用数组+链表+红黑树的数据结构来存储数据,还是通过散列,(选项卡。长度- 1)来确定在数组的位置,不过在数据的存储方面加了一个红黑树,当链表的大于等于8时,并且表的长度大于等于64时,就把这个链树化,不然还是扩容。增加红黑树,是为了提高查找节点的时间。结构如下图所示。
引用>李> <李>
基本成员变量
<强> >强能力容量<代码>/* * *初始容量 */静态最终int DEFAULT_INITIAL_CAPACITY=1 & lt; & lt;4;//即16 代码><强> max_capacity 强>最大容量
<代码>/* * *最大容量 */静态最终int MAXIMUM_CAPACITY=1 & lt; & lt;30;代码>负载系数<强> >强负载因子
<代码>/* * *负载因子 */静态最终浮DEFAULT_LOAD_FACTOR f=0.75; 代码><强> treeify_threshold 强>树化(转换为红黑树)的阈值
<代码>//链表转为红黑树的阈值,第9个节点 静态最终int TREEIFY_THRESHOLD=8;代码><强> untreeify_threshold >强转换为链表的阈值
<代码>//红黑树转为链表的阈值,6个节点转移 静态最终int UNTREEIFY_THRESHOLD=6; 代码><强> min_treeify_capacity 强>树化的最小容量
<代码>//转红黑树时,表的最小长度 静态最终int MIN_TREEIFY_CAPACITY=64; 代码>强> <强>节点链表
<代码>静态类Node实现Map.Entry {//当前节点的哈希 最后int散列; 最后K键; V值;//指向下个节点 Node 下一个; 节点(int散列,K键,V值,Node 下一个){ 这一点。散列=散列; 这一点。键=键; 这一点。值=https://www.yisu.com/zixun/value; 这一点。下一个=下一个; }代码> <强> TreeNode 强>红黑树
<代码>静态最终类TreeNode李> <李>构造方法扩展LinkedHashMap.Entry { TreeNode 父母;//父节点 TreeNode 离开;//左儿子节点 TreeNode 对的;//右儿子基点 TreeNode prev;//上一个节点 布尔红;//是否为红色 TreeNode (int散列,K键,V val, Node 下一个){ 超级(散列键,val,下一个); }代码>
<强>有参构造强>(和1.7一样)<代码>公共HashMap (int initialCapacity浮动负载系数){ 如果(initialCapacity & lt;0) 把新的IllegalArgumentException(“非法初始容量:“+ initialCapacity); 如果(initialCapacity比;MAXIMUM_CAPACITY) initialCapacity=MAXIMUM_CAPACITY; 如果(负载系数& lt;=0 | | Float.isNaN负载系数()) 把新的IllegalArgumentException(“非法装载因子:“+ 负载系数); 这一点。负载系数=负载系数; 这一点。阈值=tableSizeFor (initialCapacity); }代码><强>无参构造强>(和1.7一样)
<代码>公共HashMap () { 这一点。负载系数=DEFAULT_LOAD_FACTOR;//所有其他字段违约 }代码>李> <李>基本方法
<强>把()方法强>
执行流程:
(1)判断当桌子前有没有初始化,没有就调用调整()方法初始化。(调整方法既是扩容也是初始化)
(2)判断算出的位置我处有没有值,没有值,创建一个新的节点,插入我位置。
(3)当我前位置有值,判断头结点的散列和关键是否和传入的关键和散列相等,相等则记录这个e。
(4)与头节点的关键和散列不同,判断节点是否是树节点,如果是,调用树节点的插入方法putTreeVal()方法。(占时不了解红黑树的底层方法实现逻辑,待续)。
(5)不是树结构,那证明是链表结构,遍历链表结构,并记录链表长度binCount。主要做了两步,(1)在链表里找到和传入的关键和散列相等的基点,并记录,(2)没有找的到,创建一个节点,插入链表的尾部,并判断链表长度有没有大于等于8,如果是就调treeifyBin方法决定是否需要树化。
(6)判断前面记录的e节点是否为空,不为空证明找到了相同的基点,那就替换价值,返回oldValue。
(7)整个插入流程已经结束,接下来要判断是否需要扩容,如果(+ +大小比;阈值)满足,那么就调用扩容方法调整();<代码>公共V把(K键,V值){ 返回putVal(散列(关键)、关键值,假的,真的); }/* * *把 */最后V putVal (int散列,K键,V值,布尔alt=" HashMap源码浅析1.8”>1.8 HashMap源码浅析