hashmap结构研究

概念
HashMap定义
1 HashMap是一个散列表,存储的内容是键值对映射。
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。
也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做散列表。

2 HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。

3 HashMap 的实现不同步,线程不安全。

4 它的key、value都可以为null。

5 HashMap中的映射不是有序的。

HashMap的三个构造函数
HashMap():
构造一个默认初始容量(16)和默认加载因子(0.75)的空HashMap。

HashMap(int initialCapacity):
构造一个带指定初始容量和默认加载因子(0.75)的空HashMap。

HashMap(int initialCapacity,float loadFactor):
构造一个带指定初始容量和加载因子的空HashMap。

HashMap的参数

initialCapacity(初始容量 - 桶的数量) :默认16

loadFactor(加载因子):默认0.75

HashMap的结构图

原文链接: Javarevisited 翻译: ImportNew.com - 唐小娟

这里写图片描述

下面看详细debug时hashmap容量翻倍的情况。

起初实例化hashmap,还未放入元素之前
modCount : 0
size :0
table 容量 : 16 (默认初始容量)
threshold 临界值 : 12 (默认初始容量 *加载因子)
这里写图片描述

放入一个元素以后,
modCount : 1
size :1
table 容量 : 16(默认初始容量)
threshold 临界值 : 12(默认初始容量 *加载因子)
这里写图片描述

放入十二个元素以后,
modCount : 12
size :12
table 容量 : 16(默认初始容量)
threshold 临界值 : 12(默认初始容量 *加载因子)
这里写图片描述

放入十三个元素以后,
modCount : 13
size :13
table 容量 : 32(容量发生变化 ,2的五次方)
threshold 临界值 : 24(临界值也发生变化,2的五次方*加载因子)
这里写图片描述

放入十七个元素以后,
modCount : 17
size :17
table 容量 : 32(容量发生变化,2的五次方)
threshold 临界值 : 24(临界值也发生变化,2的五次方*加载因子)

这里写图片描述

最终放入17个元素以后
entrySet :返回值是Set集合
loadFactor(加载因子):0.75
modCount(修改次数) :17
size(大小):17
table : 静态内部类Entry,Entry数组,数组中元素个数为32
threshold (下次扩容的临界值):24
threshold = (int)Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
可以利用公式,也可以看数组中元素的个数(桶的数量),得知
capacity (初始容量):32 (由2的5次方算出32 )

注意:
HashMap有俩个参数影响性能,初始容量和加载因子。
默认初始容量是16,加载因子是0.75,容量是哈希表中桶(Entry数组)的数量,
初始容量只是哈希表在创建时的容量。
加载因子是哈希表在其容量内存储的尺度,
当哈希表中的数目超出了初始容量和加载因子乘积时,
通过rehash方法将容量翻倍。
容量必须是2的幂。
12(2的4次方 16 * 0.75,初始容量) < 17 (桶的个数) <24(2的5次方 32 *0.75,rehash后的容量)

可以看见hashmap的数组中元素的个数为32,就是32个32个bucket(桶)。

下面了解一下put方法
1 判断key是否为null值,null值时直接放入table数组第一个位置。
2 利用key的hashcode()方法计算hash值。
3 利用hash值计算数组的索引值。
4 如果俩个key的数组索引相同则放入同一个桶中的不同entry中,成为链表结构。
如果不相同,则放入下一个桶中。
5 如果有俩个相同的key,则第二次出现的key会代替原来key的位置,替换掉第一次的value值。
6 注意: 俩个不同的对象,也可能拥有相同的hashcode值,
所以他们的bucket位置相同,就会出现碰撞。这时候hashmap就会利用链表形式
将俩个对象存储在同一个桶中的LinkedList中。

下面看hashmap里数组的属性。
每个数组元素entry包含hash,key,value,next属性值。

这里写图片描述

看第23个数组,【24】里有三个entry,存放值为7, 5, 1 。
这里写图片描述

最后用表来整理一下。
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值