jdk1.8前后的HashMap

一、jdk1.7以及以前的HashMap

首先举个例子:假设现在有一所新建的幼儿园,校长要求要保留4个班级,马上要到开学季,要迎来一批新生(相当于向HashMap中添加的元素)来报道,学校会为他们分配班级,学校要保证这批新生被均匀的分配到4个班级(这4个班级相当于HashMap中的hash表)中。于是校长采用一种班级分配策略(相当于HashMap分配元素的hash算法):每个学习按照报名的顺序进行编号1,2,3……,然后用这些学生的编号N,用N除以4的余数来决定班级号。例如:一个学生的编号为5,5/4的余数是1(余数相当于元素在hash表中的位置),那么这个学生就会被分配到1班。这样一来,就能保证每只要学生数量超过4个,都会被均匀的分配到4个班级里面。

这时有人可能会提出用抓阄的形式来分配新生,由于幼儿园是新建的,所以并不知道会有多少新生来报道。如果要是为每个班级规定10个名额,如果只来10个新生,就有可能出现一种极端的情况,这10个新生全部都分配到一个班级里面。

校长一开始预计每个班级不超过20个新生(相当于HashMap源码中的threshold,也是哈西码相同的元素个数上限),因为人数太多,不方便老师管理。但是没想到招生情况乐观,每个班级的人数都超过了20,于是校长为了保证教学质量,扩充班级的个数,假设这次班级扩充为8个班级,这时为了保证所有的学生全部都均匀的分配到这8个班级,前面已经分配好的4个班级的学生也需要进行重新分配相当于HashMap的源码中resize()过程,也就是hash表的扩容过程),此时还是按照上面提到分配策略去分配,只不过除数由4变成了8,这样一来,学生就会被均匀的分配到8个班级中。

看完这个例子可能会有两个疑问:将之前分配好的4个班级重新分配会不会有些浪费时间?答:确实有些浪费资源和时间,但是没办法,为了保证均匀分配,只能这样。

HashMap的底层数据结构

HashMap作为一个容器,底层使用的就是散列的数据结构。jdk1.8以前的HashMap都是用数组+链表的形式实现的,如下图(图片来自百度)。下图中的table数组相当于学校;数组中的每个位置相当于班级号;数组中的每个元素每个班级第一个来的学生;链表相当于整个班级的学生;Entry<K,V>节点相当于学生;分配元素使用hash算法相当于分配学生的策略。

二、jdk1.8以及以后的HashMap

jdk1.8以后的HashMap引入了红黑树,使用的是数组+链表+红黑树的形式来实现的,当链表上的元素个数超过了一定个数以后就用红黑树类解决hash冲突。如下图(图片来自百度)。红黑树的引入主要是为了提高元素的查找速度。关于红黑树的介绍可以参考这篇文章

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值