快速理解HashMap(哈希表)

一、哈希表

哈希表可以简单理解为存储Key-Value(键值对)映射的集合,我们可以通过Key快速找到对应的Value,在jdk1.8(今天只聊jdk1.8)中哈希表采用了数组+链表+红黑树的方式来实现。
这是我从网上找的一张图片,先简单大家先直接看图片有个印象,对着图片看以至于不会太抽象。
在这里插入图片描述

这时可能会有疑惑,哈希表是怎么实现的,为什么搜索效率高,他又用到了那些原理,我们应该怎样使用呢?接下来容我一一道来。

二、哈希函数

哈希函数我们可以简单理解为一种数据映射的算法,当我们要存入数据的时候我们并不是直接将数据存入哈希表中,而是首先通过哈希函数计算出我们需要存入的数据对应的哈希值,这个哈希值就是对应的Key,我们需要通过哈希值来找到他在数组中对应的位置对数据进行存放,这个哈希值和源数据(Value)形成了一种映射关系,这个源数据可以是整数,字符串都是可以的,对于同一个值来说我们计算的得到的哈希值也是相同的。那有没有可能不同的Value得到了同样的哈希值,答案是有可能的,那出现了相同的哈希值时我们应该怎么解决呢?这个就联系到了哈希冲突。

三、哈希冲突(也叫哈希碰撞)

什么时哈希冲突呢?哈希冲突可以简单理解为不同的数据通过哈希函数得到了相同的哈希值,这是需要将两个数据同时存入数组中同一个,这是就发生了哈希冲突。
怎么解决哈希冲突呢?在Java中采用拉链法(也叫链地址法)来解决哈希冲突,什么是拉链法呢?通过上面的图片我们可以看出在数组的某个位置上还挂着一个链表,在同一个链表中他们对应的Key是相同的,数组中的每一个位置又相当于一个链表的头节点,所以在发生哈希冲突时在jdk1.8中采用尾插的方式对数据进行插入。

四、哈希表的扩容机制

接下来需要引入两个个知识点
① 哈希表的初始长度:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

这句话是HashMap中的源码,表示哈希表的初始长度为16
② 负载因子 :

static final float DEFAULT_LOAD_FACTOR = 0.75f;

这个0.75就表示负载因子的大小,这个负载因子表示什么意思的,有什么用的?
负载因子主要是和哈希表的扩容有关,那么我们就要了解哈希表什么时候扩容。因为哈希表的初始值是16,负载因子是0.75,所以我们可以计算出哈希表的一个阈值,16*0.75=12,这个12就是哈希表初次扩容的阈值,扩容后长度变为原来的两倍,通过这个负载因子我们可以看出,哈希表并不是数组中的每一个位置都存放着数据,由于负载因子的存在每当数组中的Key的个数达到阈值时就会出发扩容。

五、哈希表中的红黑树

先简单介绍一下红黑树 : 红黑树可以简单理解为一种平衡二叉搜索树,但红黑树的平衡是相对平衡,并不是AVL树的那种绝对平衡。我们只要先记住红黑树是一种搜索效率很高的二叉树即可。
之前我们说到哈希表是通过数组+链表+红黑树来实现。我们了解到了数组是来对应一个Key值,当发生哈希冲突时会将数据尾插在数组下的链表中。那什么时候用到红黑树呢?
哈希表中规定当链表的长度大于8并且数组长度达到64的时候才会将链表升级为红黑树,当红黑树的节点小于6时红黑树又会退化为链表。

六、性能分析

为什哈希表查询快呢?

哈希表的查找数据可以分为两步,第一步是将键(Key)通过哈希函数映射为数组中的索引,第二步遍历链表或者在红黑树中查找数据通过值(Value)来唯一确定所查找的数据。
数组查询的时间复杂度O(1);链表和红黑树的查找的时间复杂度可以看作是O(logn)。
所以纵观整个哈希表的查询过程时间复杂度可以看作O(logn)。
效率确实很高。

七、哈希表的使用

哈希表的常用方法 :
在这里插入图片描述
①put()方法用来对数据进行存储;
②get()方法用来对数据进行查询;
③getOrDefault()方法是当Map集合中有这个key时,就使用这个key值;如果没有就使用默认值defaultValue;
④containsKey()方法是判断Map集合对象中是否包含指定的键名
⑤remove()方法用于数据的删除;
⑥clear()方法用于清空哈希表;
⑦isEmpty()用于判断哈希表是否为空;
⑧size()方法用于计算哈希表的长度。

看完这些相信对哈希表有个初步的掌握。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值