hashmap

Hashmap

HashMap简介:

想必大家都听说过Hashmap,hashmap是一个常用的java集合,是以key-value对来存储的,一个键对应一个值,不存在重复的键。它是由数组和链表组合成的,因为数组的查询查找快,删除,插入等比较慢,而链表是查询慢,插入删除快,结合数组和链表可以充分发挥它们的优势,我们可以将HashMap看做是链表的数组,即每个数组元素存放的是一个链表,示意图如下:
在这里插入图片描述

jdk1.8之后引入了红黑树,当一个链表存放的数据过大时访问速度变慢,此时将链表转为用红黑树结构,红黑树的平均查找时间为3,而链表的平均查找时间为n/2,所以当每个链表的数据个数小于6时就用链表比较快,当大于6时就用红黑树存储了,但是实际上jdk的、将这个界限化为了8,达到8个元素才转为红黑树存储,当然只是转换该数组元素而已,此时hashMap中数组存储的应该有链表也有红黑树结构,如下:

在这里插入图片描述

HashMap的机制:

因为HasMap是以键值对存在,键的作用就是用来确定值的存储位置的,基本原理将key作为参数,调用哈希函数生成一个尽量减少冲突的int型值叫做hashCode(在源码中为 hash(Object key)),hashCode再对数组大小进行取模就可就可以得到一个比容量要小的数了(在源码中为indexFor方法),那么他就是要存放的数组索引,hash函数的作用就是尽量减少冲突,即尽可能让数据存在不同的数组下标中,对于使用了什么哈希函数并不用去纠结。

HashMap默认的容量

HashMap的容量(capacity)指的是数组的大小,大小(size)指的是HashMap中真是存在的键值对个数,那么在new出来一个HashMap时如果不指定它的容量,它的容量默认是16,那为什么要取16呢?HashMap追求的就是快,HashMap求数组索引的时候是要获得hashCode对容量的模,那么在数学中我们一般写作 hashCode%capacity ,但是HashMap嫌它太慢了,就另一种更快方法来求得模 hashCode&(capacity-1),这样求得的结果大小是一样的,但是有一点要求capacity必须是2的指数大小,大家不信可以自己尝试。这样hashMap为了快就将默认容量设置为2的指数大小,取16的原因是:太小了的话需要频繁扩容,太大的话又浪费空间,折中就将其设置为一个期望值优的数了。

HashMap扩容

如果hashCode值相同,叫做碰撞,碰撞之后会放在同一下标的数组中,就成了链表了,数据多了就影响效率了,在数组占满率到达某个临界值要对数组进行扩容,在HashMap中这个临界值的的计算公式为:threshold = loadFactor * capacity(loadFactor为负载因子,表示装满程度,这里取0.75),也就是说当有0.75倍的数组容量时就要扩容了,有人会疑问为什么不装满再扩,因为要考虑碰撞的问题,并不一定每个数据都会放到不同的数组元素中,可能某个数组元素已经存了一个很长的红黑树了,而此时如果某个数组元素还是空的,就一直扩不了,那就会影响整体效率了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值