HashMap的原理

HashMap的是java的中使用最为频繁的地图类型,其读写效率较高,但是因为其是非同步的,即读写等操作都是没有锁保护的,所以在多线程场景下是不安全的,容易出现数据不一致的问题。在单线程场景下非常推荐使用。

HashMap是由数组和链表两种数据结构组合而成的,其节点类型均为名为条目的类(后边会对条目做讲解)。采用这种数据结果,即是综合了两种数据结果的优点,既能便于读取数据,也能方便的进行数据的增删。

每一个哈希表,在进行初始化的时候,都会设置一个容量值(容量)和加载因子(loadFactor)。容量值指的并不是表的真实长度,而是用户预估的一个值,真实的表长度,是不小于容量的2的整数次幂。加载因子是为了计算哈希表的扩容门限,如果哈希表保存的节点数量达到了扩容门限,哈希表就会进行扩容的操作,扩容的数量为原表数量的2倍。默认情况下,能力的值为16,loadFactor的值为0.75(综合考虑效率与空间后的折衷)。
数据写入。以HashMap(String,String)为例,即对于每一个节点,其键值类型为String,value值类型也为String。在向哈希表中插入数据的时候,首先会计算出键值的的hashCode,即key.hashCode()。关于的hashCode方法的实现,有兴趣的朋友可以看一下JDK的源码(之前看到信息说有一次面试中问到了这个知识点)。该方法会返回一个32位的int类型的值,以int h = key.hashCode()为例。获取到h的值之后,会计算该键对应的哈​​希表中的数组的位置,计算方法就是取模运算,h%table .length。因为表的长度为2的整数次幂,所以可以用h与table.length-1直接进行位与运算,即是,index = h&(table.length-1)。得到的索就就是放置。新数据的位置

如果插入多条数据,则有可能最后计算出来的指数是相同的,比如1和17,计算的指数均为1.这时候出现了散列冲突.HashMap解决哈希冲突的方式,就是使用链表。个链表,保存的是指数相同的数据。

  • 数据读取。从哈希表中读取数据时候,先定位到对应的索引,然后遍历对应位置的链表,找到关键值和的hashCode相同的节点,获取对应的值值。
  • 数据删除。在HashMap中中,数据删除的成本很低,直接定位到对应的索引,然后遍历该链表,删除对应的节点。哈希表中数据的分布越均匀,则删除数据的效率越高(考虑到极端场景,数据均保存到了数组中,不存在链表,则复杂度为O(1))。
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值