剖析HashMap

一: 图解说明HashMap

HashMap最擅长的事情就是快速索引,那么它到底是如何组织数据来达到这一目的的呢? 我们先抛出这个问题,往下看。
在介绍HashMap之前 我们先来看一看基础的数据结构,如果比较了解可以直接跳过

数组

提起数组,相信大多数人都不陌生,那么数组到底是什么,数组的本质是一块连续的内存空间,存放着具有共同特性的内容,因为是一块连续的内存,我们就可以快速的定位,我们可以通过数组的下标直接对其进行操作。数组的缺点让我们看下面这张图
在这里插入图片描述我们定义了一个长度为7的数组,里面存放着4个数据,现在我们要将270这个数据插入到索引为1和2的中间,这个时候需要将289和320两个数据往后移动一位,然后才能将270添加到相应的位置上,看下面的图
在这里插入图片描述在这里插入图片描述这样数组的缺点就是显而易见的,只有插入的节点是最后一个的时候,方便,其余的都是比较复杂和麻烦,同样的类比删除一个节点。

  • 数组的优点:连续的内存,可以通过索引快速的寻址
  • 缺点: 插入删除节点麻烦
单链表

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。因为只有一个指针结点,称为单链表。在这里插入图片描述单链表中三个概念需要区分清楚:分别是头指针,头节点和首元节点

  • 头结点:有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。特别注意:若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。

  • 头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)

  • 首元结点:链表中第一个元素所在的结点,它是头结点后边的第一个结点

  • 头结点和头指针的区别:头指针是一个指针,头指针指向链表的头结点或者首元结点;头结点是一个实际存在的结点,它包含有数据域和指针域。两者在程序中的直接体现就是:头指针只声明而没有分配存储空间,头结点进行了声明并分配了一个结点的实际物理内存。
    在这里插入图片描述单链表中可以没有头结点,但是不能没有头指针!
    返回正题,对于单链表来说,每一个节点都是有指针指向的,添加或者删除相对于数组而言是方便快捷的,例如将上面的数组的这个添加270的例子放到单链表中去操作,我们只需要去遍历整个单链表去找到插入的位置,然后重新设置指针的指向即可,插入元素后面的所有节点都是不需要变化的,对于空间的消耗较小。
    在这里插入图片描述

  • 单链表的优点:插入和删除节点方便

  • 缺点: 查询效率低下 O(n)

HashMap

HashMap说到底就是一个容器,用来存放数据的,我们集合数组和单链表的特性,来了解HashMap是如何达到快速索引.首先它用到了数组的快速定位的特性。我们插入到数组当中的目的就是快速定位
插入到数组中只是快速定位的第一步。插入到数组中的数据也要快速的找到它,可以建立插入值和数组所在下标位置之间的关系,假设我们现在有一个int类型的数组,我们建立pos=key%size,这里的key值就是我们要插入的内容,size就是数组的大小,比如我们要插入一个100,数组的size是10,此时pos=0,如果是201那么得到的pos就是1,元素插入到数组下标为1的位置上,例如下图在这里插入图片描述这里就会出现一种问题,如果此时下标为0的位置上有元素,但是我们现在又要插入200这个值,200对应的pos也是0,在数组中同一个位置放置两个值,显然是不可能的,此时我们需要另一种数据结构的帮助,单链表。我们将数组声明为链表的方式,如下图在这里插入图片描述使用链表的特性,此时插入200的时候就会产生冲突,HashMap是如何解决冲突的呢,在计算求余后,pos相同,我们就使用单链表来进行扩展.将此时的100位置下的Next指针,指向200这个节点,如下图在这里插入图片描述在解决了冲突的情况下,并没有满足到快速定位的目的,比如我们查找100元素,首先也是定位到0这个位置上,然后来进行比较,这样就又回到了单链表的缺点,当我们链表的长度比较长的时候,遍历起来效率低下,在效率最差的时候,我们不得不比较N次,才能确定某个元素在不在我们的HasMap容器中,HashMap在Jdk1.8的之后又进行了优化,引入了树形结构,红黑树,在链表长度过于长的时候,将链表转换为红黑树,来提高查询性能,此时的结构如下在这里插入图片描述图解小结在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值