深入理解HashMap

HashMap在JDK1.7中采用数组+链表的数据结构,通过哈希算法分配元素,负载因子默认为0.75。当冲突较多时,链表长度超过8会转换为红黑树以优化查询效率。在JDK1.8中,引入红黑树进一步减少搜索时间,但会考虑空间占用,当节点数小于6时,又会退化为链表。这种设计兼顾了空间与时间的平衡。
摘要由CSDN通过智能技术生成

对于jdk1.7来说HashMap采取的是数组+链表的形式来进行储存的,但是为啥是采取数组+链表呢,我理解的原因是:

首先得了解到数组是一块连续的空间、链表是不连续的。之所以是数组+链表是为了更少的开辟空间,提高效率

对于key来说,我们首先要将key的ascii码进行hash,获取到的值作为数组的下标进行储存,当然会存在哈希值一样的(因为数组会被直接盖住),这个时候就会进行链表的头插法,数组的长度初始值为16每次扩容2,不过呢在扩容之前有还有一个负载因子,代表了table的填充度有多少,默认是0.75。

在hashmap源码中有一段网址,大概意思就是说HashMap遵循Poisson_distribution,Poisson_distribution这就是泊松定律呀,

  * nodes in bins follows a Poisson distribution
 * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
     * parameter of about 0.5 on average for the default resizing
     * threshold of 0.75, although with a large variance because of
     * resizing granularity. Ignoring variance, the expected
     * occurrences of list size k are (exp(-0.5) * pow(0.5, k) /
     * factorial(k)). The first values are:
     *
     * 0:    0.60653066
     * 1:    0.30326533
     * 2:    0.07581633
     * 3:    0.01263606
     * 4:    0.00157952
     * 5:    0.00015795
     * 6:    0.00001316
     * 7:    0.00000094
     * 8:    0.00000006
     * more: less than 1 in ten million

负载因子为啥是0.75而不是1或者0.5呢?
答案:因为是0.5的时候,数组容量达到一半就开始扩容,hash冲突就会少一点,链表查找就会快一点,可是消耗的空间就会多一倍呀!!这就是牺牲空间来保证时间的做法。当负载因子为1的时候,这种情况下,虽然空间变小了,但是需要做查询的时间就高类呢!!!这就是牺牲了时间来保证空间的利用率。所以说呢就是取一个折中的办法,就只能是0.75了(其实还是根据泊松定律来得)

对于jdk1.8数组+链表+红黑树

为什么有了红黑树还要链表?
答案:先看下面这段源码,他是说因为树节点所占空间是普通节点的两倍,所以只有当节点足够多的时候,才会使用树节点。也就是说,节点少的时候,尽管时间复杂度上,红黑树比链表好一点,但是红黑树所占空间比较大,综合考虑,认为只能在节点太多的时候,红黑树占空间大这一劣势不太明显的时候,才会舍弃链表,使用红黑树。还有就是红黑树查询快,插入慢。

     * Because TreeNodes are about twice the size of regular nodes, we
     * use them only when bins contain enough nodes to warrant use
     * (see TREEIFY_THRESHOLD). 

链表转化为红黑树的条件是节点个数超过8

static final int TREEIFY_THRESHOLD = 8;

红黑树转化为链表的条件是节点个数为6

static final int UNTREEIFY_THRESHOLD = 6;

为什么是这两个数字呢,其实上面已经说过了, 链表转化为红黑树还是红黑树转化为链表取这两个数字都是为了提高速率,那为什么是这两个数字呢,还是因为一个那一个概率论公式泊松定理得到的(emmm,具体就不分析了)

分析起来头都大了,有错误的地方希望大家多多纠正哦,还有一些点下次再分析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值