什么是HashMap???一些详细的说明

1.什么是HashMap???

它是java集合框架的一种实现类,它存储的内容是键值对(key-value)映射.

它继承与AbstractMap抽象类.

它的底层实现原理是,在jdk1.8之前是链表+数组在jdk1.8之后是数组+链表+红黑树,根据哈希函数计算键的哈希值,根据哈希码存储到对应的数组位置上.

它的实现不是底层同步的,意味这不是线程安全.它的key和value可以有一个null.

2.一些HashMap底层的详细信息.

1.源码中重要的常量:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;  默认容量16 
static final int MAXIMUM_CAPACITY = 1 << 30;  最大容量2^30
static final float DEFAULT_LOAD_FACTOR = 0.75f; 默认加载因子0.75
static final int TREEIFY_THRESHOLD = 8;链表长度大于默认值8转化为红黑树.
static final int UNTREEIFY_THRESHOLD = 6; 红黑树存储的元素个数小于6,转为链表.

2.HashMap的扩容

当HashMap里面的元素越来越多时,产生哈希冲突的几率就会越来越高,因为数组的长度是默认的,为了降低哈希冲突,就要对集合扩容.

怎么扩容的?

当元素个数超过了数组大小*loadFactor时,就会扩容,loadFactor的默认值为DEFAULT_LOAD_FACTOR = 0.75,也就是说在默认的情况下,数组大小DEFAULT_INITIAL_CAPACITY=16;那么当元素个数超过了16*0.75=12的时候,会调用resize()方法将数组的大小扩容为2*16=32,也就是原来的2倍.然后重新计算每个元素在数组的位置.

3.分析put()方法添加数据的过程

1)判断键值对是否为空,为空计算哈希值,找到到数组索引位置直接添加数据.

!!!不为空判断元素个数是否达到临界值(数组的容量*加载因子)?, --没有达到计算哈希值,插入到数组索引位置接2). --达到了调用resize()方法扩容为当前的2倍,在插入到数组索引位置接2)

2)判断当前位置是否有数据?有 当前的key和存在的key是否相等? 是替换value值.如果不想等会出现哈希冲突,

怎么解决2)出现的哈希冲突呢?

链式寻址法

把存在Hash冲突的key以单向链表的方式来进行存储。在jdk1.8之后通过链式寻址法和红黑树的方式解决Hash冲突问题,其中红黑树就是为了优化链表过长导致时间复杂度增加的问题,当链表长度大于8并且给Hash表的容量大于64的时候,再向链表中添加元素,就会触发链表向红黑树的一个转换。

再hash法

某个Hash函数计算的Key存在冲突的时候,再用另外一个Hash函数对这个Key进行Hash,一直运算直到不再产生冲突为止。

这种方式会增加计算的时间。性能上会有一些影响。

要不然就继续扩大数组.


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值