学习hashMap总结

基于java 1.6

         HashMap和其他的Map一样,都有由key和它的value构成。但是不同的Map其key的存储方式是大不相同的。HashMap较其他Map具有更好的查询效率,这是由于HashMap采用了Hash算法。每一个key本身都具有一个获取hashCode的方法。这些hashCode通过hash算法,被转化为一个个序号,对应“横向”链表上的存储位置。

         当序号相同且key的值不同时,在这个位置上就会形成一个“纵向”的链表。在这个链表中先添加的key处于链表的末端,后添加的处于链表的前端。链表的存储单元为 Entry<k,y> ,在这个类中有一个还有一个类型为Entry<k,y>的参数,名为nextnext指向的是下一个Entry<k,y>的地址,HashMap就是以这样的方式形成了一个“纵向”的链表。


       hashMap还具有自动扩张的功能。每当map中的容量达到threshold的时候,hashMap就会通过resize()方法扩张一倍。Resize()的过程是比较消耗性能的,所以如果事先知道存储的大概范围时,也可以预先设置Map的大小,从而降低扩张带来的消耗。threshold的算法是size*loadFactor,loadFactor是一个比例参数,决定了多大比例的长度作为threshold,一般而言loadFactor的值为0.75。如果一个hashMap的长度为16loadFactor的值为0.75,那么它的临界值为12,当添加的元素达到12时,这个map就会扩张一倍达到32.

 


hashMap可以通过构造函数在初始化的时候设置hashMap的各项参数。它提供的构造参数有HashMap(int size,float threshold)HashMap(int size),HashMap() HashMap(Map map)。size是指Map的大小,然而这个值不一定会成为HashMap的最终大小,它会最终转换为最接近 2的N次方值。在HashMap(int size,float threshold)的源码里,有这样的代码:

       其中j为最终的大小,i就是我们传递过来的size,通过位运算,j的最终取值为稍大于size的2的N次方值。以下是默认的构造函数HashMap():

       可以看到loadFactor的默认值为0.75,默认临界值为12(并不是很大),而“横向”的链表其实只是一个数组。如果事先知道HashMap的大小,就应该使用HashMap(int size,float loadFactor)或HashMap(int size)为这个HashMap设置一个合适的大小。即便HashMap有着自动扩张的能力,但是这个功能会消耗不少性能,所以事先设置长度是更好的办法。

 


       hashMap的大小总是2n次方。这是经过计算得出的最佳大小,在这个大小上,hashCode的映射可以达到最小碰撞的效果。

      1.将key的hashCode经过HashMap的hash算法后获取的值设为A

      2.将HashMap的总长度设为S

那么这个key对应的hashMap中的位置实际应为table[A & (S-1)] 。如果总长度总为16,那么在16-1在二进制对应的值为1111,这个值具有最好的匹配度,因为它每一位都为1。它就像一面光滑的镜子,可以将Hash后的值均匀的映射到table的各个位置上。

参考文档:

http://alex09.iteye.com/blog/539545

http://www.iteye.com/topic/539465/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xp9802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值