HashMap原理和底层实现

最近研究了一下java中比较常见的map类型,主要有HashMap,HashTable,LinkedHashMap和concurrentHashMap。这几种map有各自的特性和适用场景。使用方法的话,就不说了,本文重点介绍其原理和底层的实现。文章中的代码来源于jdk1.9版本。

HashMap特点及原理分析

特点

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

原理

HashMap的整体结构,如下图所示:

在这里插入图片描述
根据图片可以很直观的看到,HashMap的实现并不难,是由数组和链表两种数据结构组合而成的,其节点类型均为名为Entry的class(后边会对Entry做讲解)。采用这种数据结果,即是综合了两种数据结果的优点,既能便于读取数据,也能方便的进行数据的增删。
每一个哈希表,在进行初始化的时候,都会设置一个容量值(capacity)和加载因子(loadFactor)。容量值指的并不是表的真实长度,而是用户预估的一个值,真实的表长度,是不小于capacity的2的整数次幂。加载因子是为了计算哈希表的扩容门限,如果哈希表保存的节点数量达到了扩容门限,哈希表就会进行扩容的操作,扩容的数量为原表数量的2倍。默认情况下,capacity的值为16,loadFactor的值为0.75(综合考虑效率与空间后的折衷)。

数据写入。以HashMap(String, String)为例,即对于每一个节点,其key值类型为String,value值类型也为String。在向哈希表中插入数据的时候,首先会计算出key值的hashCode,即key.hashCode()。关于hashCode方法的实现,有兴趣的朋友可以看一下jdk的源码(之前看到信息说有一次面试中问到了这个知识点)。该方法会返回一个32位的int类型的值,以int h = key.hashCode()为例。获取到h的值之后,会计算该key对应的哈希表中的数组的位置,计算方法就是取模运算,h%table.length。因为table的长度为2的整数次幂,所以可以用h与table.length-1直接进行位与运算,即是,index = h & (table.length-1)。得到的index就是放置新数据的位置。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值