HashMap相关一些内容

正文

冲鸭 ! 冲鸭!

HashMap相关

什么是HashMap:

HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。

HashMap的内部实现:

HashMap的是给予hashing原理实现,当通过put存储对象时,会先通过k计算出hashcode值,然后通过hashcode值确定相应哈希桶的位置,然后将entry储存进去,当然get的时候也通过值计算hashcode值来确定哈希桶来获取对应的值

当两个值的hashcode相等会如何:

当hashcode相同时,哈希桶也相同,这是就发生哈希碰撞,产生链表,两个entry存于链表中,而当链表大于8就会改变为红黑树结构(1.8)

当两个值的hashcode相同,如何获取正确的值:

会通过hashcode找到相应的哈希桶,然后遍历链表并用equals方法把key和节点值比较,找出正确值

HashMap超出负载因子的定义会怎么办:

HashMap的容量超过0.75时会进行rehash来扩容为原容量的两倍,再用hash算法算出hashcode,找到新的哈希桶并将entry放入,相当消耗性能,所以一般要初始化HashMap容量((储存数量/负载因子)+1),不能确定就默认16
扩容期间链表中的元素顺序会反过来,放到新的哈希桶的时候,HashMap会将元素放在头部,并不会放在尾部,防止尾部遍历

多线程下HashMap会存在竞争问题: (?? 多线程为什么要用HashMap)

当两个线程同时进入,都发现容量不够,并同时进入扩容,会死循环的

哈希桶必须为2的n次方(合数):

主要是为了减少哈希碰撞,数据均匀分配,hashMap每次存数据的时候都要考虑把数据均匀的放在数组的每个位置,且每个位置只有一个元素的话就减少了链表的出现,减少了开销,提高查询效率
因为计算机是二进制运算,1和1与才为1,其他均为0,所以当值为2的n次方时hash&(length-1) == hash%length(取余运算性能不如位运算), length-1的二进制为0+N个1,就能确保数组每个位置都可以存放值,
而素数时,就可能有些位置永远不倍存放数据,浪费资源,
举个栗子 :

假如不是按2的n次方,假设为length = 15,hash= 17,则10进制取余运算为2,二进制位运算为10001&01110 =0,不会等于10进制的的运算结果;而实际上length-1 = 14 = 01110和任何的hash相与,
最后的一位的0都会被舍弃,所以任何的hash值和01110相与的结果都不会出现1101(13),1001(9)等数据,所以相当于table的数组中index =13或者9的位置永远不会保存到数据,造成空间浪费;

HashMap线程安全吗,多线程下存在什么问题:

HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表形成环,一旦成环,Entry的next节点永远不为空,产生死循环,cpu猛涨

之前看到一个很好的数组,链表,哈希的区分栗子:

上体育课的时候,老师说:你们站一队,每个人记住自己是第几个,我喊到几,那个人就举手,这就是数组。
  
老是说,你们每个人记住自己前面的人和后面的人,然后老师只知道第一人是谁。 然后你们各自由活动,
老是要找某一个人,是不是每次都是从第一个开始往自己身后的人开始传达?
这就是链表。
  
老师说: 大家1,2,3,4报数,凡是报1,为1队,凡是报2的为2队。。。。  
这就是散列(哈希)。而这个4就相当于预定义好的桶的个数。。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值