HashMap源码解读

    科技2022-07-11  87

    HashMap源码解读

    1.HashMap初始化容量为什么要2的幂次方?1.1初始值不为2的幂次方时:1.2初始值为2的幂次方时 2.将链表转换为红黑树3.HashMap扩容机制4.如何设置HashMap的初始化问题描述


    提示:个人笔记,下面案例可供参考

    HashMap(线程不安全):默认容量是16,加载因子是0.75,每次扩容 容量会增张两倍 JDK1.7:数组+链表: JDK1.8:数组+链表+红黑树 链表长度大于8并且数组长度大于64 会变成红黑树

    1.HashMap初始化容量为什么要2的幂次方?

    计算流程: 1.会根据hashMap的key值获取hash值. 2.传入的初始化值减1与hash值进行’与‘运算. 3.计算出的结果为数组角标
    1.1初始值不为2的幂次方时:

    假设n为14,n-1的二进制为0000 1101,与hash值运算结果如下

    假设n为13,n-1的二进制为0000 1100,与hash值运算结果如下 *可以看到这样会增加hash碰撞的几率(计算出的结果一样)


    1.2初始值为2的幂次方时

    假设n为16(2的幂次方),n-1的二进制位0000 1111,与hash值运算结果如下

    假设n为8(2的幂次方),n-1的二进制位0000 1111,与hash值运算结果如下


    2.将链表转换为红黑树

    1.根据哈希表中元素个数确定是扩容还说树形化。 2.如果是树形化遍历桶中的元素,创建相同个数的树形节点,复制内容,建立联系。 3.然后让桶中的第一个元素指向新创建的树根节点,替换桶的链表内容为树形化内容。

    3.HashMap扩容机制

    1.当HashMap中的元素个数超过了数组大小(数组长度*负载因子)时,就会进行扩容。默认情况下,数组大小为16,那么当HashMap中的元素个数超过了16×0.75(默认)时,就会把数组的大小扩展为2×16=32,即扩大了一倍,然后诚信计算每个元素在数组中的位置。 2.当HashMap中的其中一个链表的对象个数如果达到了8个,此时如果数组长度没有达到64,那么HashMap会先扩容解决,如果已经达到了64,那么这个链表会变成红黑树,节点类型由Node变成TreeNode类型。如果树节点个数小于6时,会再把树转为链表。 3.扩容之后的节点要么就在原来的位置,要么就被分配到“原位置+旧容量”这个位置上。 4.在扩容HashMap的时候,不需要重新计算hash,只需要看看原来的hash值新增的那个bit是1还是0就可以了,是0的话索引没变,是1的话索引变成“原位置+旧容量”。

    4.如何设置HashMap的初始化问题描述

    1.我们想要在代码中创建一个HashMap的时候,如果我们已知这个map中即将存放的元素个数,给HashMap设置初始容量可以在一定程度上提升效率。公式:“所需要的使用个数/0.75+1“。 2.JDK并不会直接拿用户传进来的数字当默认容量,而是会进行一番运算,最终得到一个2的幂次方(3->4 ,7->8 ,9->16)。
    Processed: 0.011, SQL: 8