HashMap剖析

1、HashMap是什么?

- HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射。

- HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改。

- HashMap是非synchronized,所以HashMap速度快。

- HashMap可以接受null键和值,而Hashtable则不能。

2、HashMap中put的工作原理是什么?

put时,先对键调用hashCode()方法,计算并返回的hashCode是用于找到Map数组的bucket位置来储存Node对象,然后根据key和value生成node对象,再把生成的node对象存入计算后的位置。

3、HashMap为什么不能使用基本类型作为key和value?

HashMap在put时,会调用key的HashCode方法,而基本类型没有HashCode;如果声明时不指定类型,put时可以使用基本类型作为key是由于HashMap会包装成引用类型;value不能为基本类型是由于put方法添加了泛型。

4、HashMap的indexFor方法为什么使用&运算,以及容量为什么是2的n次方?

第一:&运算是使用二进制运算(参加运算的两个数的二进制按位进行运算,每一位作比较,1&1=1,其他都为0,例如3&2 = 0111&0010 = 0010,十进制结果则为2)效率高。

第二:减少Hash碰撞,减少bucket的链表深度,提高bucket的利用率和查询效率。2的n次方与indexFor方法关联使用能使元素分配相对均匀;2的n次方二进制为1后面跟n个0,而length-1(indexFor方法为h&(length-1),h为随机数)的二进制则全是1,当h小于length时,h&(length-1)的值就为h,如果h大于length,h&(length-1)结果即h后四位二进制做&运算后的值,也就是%运算后的余数。这样能使元素分配平均,h为1,h&(length-1)为1,h为2时,h&(length-1)为2,而容量不为2的n次方,length-1后的二进制不全为1,会导致h不同时计算后的index也相同,即一个数组存放多个node,导致链表深度变大。

5、HashMap多线程下出现的问题?

- 多线程put操作后,get操作导致死循环。

- 多线程put非NULL元素后,get操作得到NULL值。

- 多线程put操作,导致元素丢失。

6、HashMap死循环产生原因分析?

HashMap进行存储时,假设size超过当前最大容量*负载因子时候会发生resize。resize方法中调用了transfer()方法,而这种方法实现的机制就是将每一个链表转化到新链表,而且链表中的位置发生反转,造成链表回路。从而发生get()死循环。根源是新链表的顺序跟旧的链表是完全相反。

例如:假如有两个线程P1、P2,以及链表 a,b,c

1.P1先运行,运行完"Entry<K,V> next = e.next;"代码后发生堵塞,或者其它情况不再运行下去,此时e=a, next=b。

2.而P2已经运行完整段代码,于是当前的新链表newTable[i]为b,a,c。

3.P1又继续运行"Entry<K,V> next = e.next;"之后的代码,则运行完"e=next;"后,a.next=b,同时b.next=a。则造成环形链表,这时get时就会一直死循环。

JDK1.8维护了两对指针,维护head和tail两个链表,依次在末端添加新的元素来保证新链表的顺序和旧的链表一致,虽然JDK8解决了死循环问题,但多线程下还是会有其他问题,所以多线程尽量用ConcurrentHashMap。

7、JDK1.8下的HashMap结构变化?

由数组加链表结构变成数组+链表+红黑树,当链表深度大于8时,则转换为红黑树(一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,非红即黑。通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍,适用于搜索,插入,删除操作较多的情况)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值