HashMap 源码分析

 

 

 

 下面来看看get(Object key)方法的流程以及源码

 

 

      从上面源码中可以看出:当系统决定存储 HashMap 中的 key-value 对时,是没有考虑 Entry 中的value的,仅仅只是根据key 来计算并决定每个Entry 的存储位置。这也说明了前面的结论:我们完全可以把Map集合中的value 当成key的附属,当系统决定了key 的存储位置之后,value 随之保存在那里即可。

    

     int hash = hash(key.hashCode());这句来调用的上面的方法,可以看到hash(int h)方法里面纯粹的数学计算。对于给的对象,

hashCode()的值是相同的,那么算出的hash码也会是相同的。

     接下来调用了此方法

     

      通过h &(table.length -1) 来得到该对象的保存位置,通过前面的定义可以知道,HashMap 底层数组的长度总是2的n次方,经过N次推算可以得出hash值与偶数与,得到的相同的值的几率比奇数大,如果相同的值多了,数据便会分配到相同的数组的位置上,链表中的值就多了,从链表中查询效率也就比较低了。

     而hash值与奇数与,得到相同的值的几率低,便会分配不同的数组的值,查询只需要一次就好,效率相对来说也就比较高。

     下面给出例子

      一个哈希值是8,二进制是1000,一个哈希值是9,二进制是1001。和1111(奇数)与运算后,分别还是1000和1001,它们被分配在了数组的不同位置,这样,哈希的分布非常均匀。

      再和1110(偶数)与,分别得到的值是1000和1000,得到了相同的值,哈希值8和9的元素多被存储在数组同一个位置的链表中。链表中的值越多,操作时对链表循环越多,效率也就越低了。所以,一定要哈希均匀分布,尽量减少哈希冲突,减少了哈希冲突,就减少了链表循环,就提高了效率。

 

   下面这张图显示了HashMap的存储方式,数组+链表。

    MAP

 

 下面来看看put(K key, V value)方法,了解整个流程及源码分析

 

 

    如果数据大小是固定的,那么最好给HashMap设定一个合理的容量值。不然不停的扩容,不停的给所有的元素重新哈希,那效率就惨了。

 

HashMap就到这了,主要的几个方法都简略的分析了下,把HashMap的结构弄清楚了,其余的方法步骤都差不多。

源码中可以看到HashMap不是同步的

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值