HashMap

HashMap

 

HashMap的底层结构仍然是数组,下图中,hashMap有一个table属性,其是一个Node数组,这个Node实现了Map.Entry接口,即map所有的entry都是存放到这个数组里面的。

下面我将用反射技术获取hashMap中的这个数组到底是如何存放数据的(注意Node<K,V>有一个next属性,这个属性很重要,也体现了HashMap设计的优美)

 

 

上图中可以清楚地看出通过反射技术获取到了HashMap存放Entry的数据结构即 Node数组,那么hashMap是如何存放数据的呢?hashMap在put的时候会先计算key的hash值,然后hash值除以node数组的大小求余数。那么这个余数就是该Entry在node数组中的下标(如程序中的a,hash值为97,所以其下标为1)。当下标相同时(如a 和q),hashmap会根据put的顺序,将后一个put进去的entry放在在相同下标的前一个entry的next属性中(前提是两个entry不相等,否则将覆盖)。HashMap存放数据有两个很重要的依据,一个是hash值、一个是判断两个对象是否相等(如果两个entry的hash值一样并且equals方法返回true那么后put的值将会覆盖前一个值),这也是为什么HashMap的key对象重写hashCode()、equals()两个方法很重要。

另外需要注意的是,如果数组某一个下标下面维护的链表长度超过8的时候,该链表将会被"树化"即由链表结构转化为二叉树结构(见下图),这样是为了防止当链表过长时,遍历链表的时间复杂度将是O(n),改为二叉树结构时间复杂度将是O(logn)。

此外,hashmap的默认的table数组大小为16,但是我们可以通过new HashMap(n);来指定table的大小,但是数组的真实大小m可能并不等于n, m 为大于等于n的最小的2的x次幂。如:n为3则m=4=2^2. n为6则m=8=2^3,n为13则m=16=2^4.

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值