一篇文章让你精通:java集合讲解(五,哈希表)

26 篇文章 1 订阅
13 篇文章 0 订阅

相信大家看过前面的内容后,对集合set有一定的了解,当我们重写定义对象时,要对对象的hashCode和equals方法进行重写。关于为什么我相信大家肯定和我有一样想法,所以小编此篇文章就来讲讲什么是哈希表。

哈希表原理

         当在无序数组中按照内容进行查找,效率低下,时间复杂度O(N),在有序的数组中数组中按照内容查找,可以使用折半查找,时间复杂度O(long2N),在二叉平衡树中按照内容进行查找,时间复杂度O(long2N),按照数组索引进行查找,不进行比较与计数,直接计算得到时间复杂度O(1)(索引的位置=起始位置+元素大小*索引)

问题:不按索引查找,按内容进行查找不进行比较与计数直接计算得到时间复杂度O(1)?

有,这个就是哈希表。通过跟给定的字值进行比较,来进行比较,效率取决于比较次数。(理想状态下就是比较一次时间复杂度O(1))需要记录存储位置与其关键字之间确定的对应关系,使每一个记录位置与关键字相对应。

哈希表的特点

hashtable,哈希表也叫散列表,特点:快,非常快

结构:存在这很多种结构,最流行与好理解的是:顺序表+链表

主结构,顺序表,每一个顺序表节点单独引出链表

哈希表是如何添加数据的过程(非常重要)

1,计算哈希码,不管内容加入什么,都通过计算得到一个整数

@Override
public int hashCode() {
        return Objects.hash(属性);
    }

2,根据哈希码计算出在哈希表中存储位置(例如通过y=key(x)=x%11,根据取模安排在顺序表后面,如上图,x表示哈希码,key()表示函数“对应关系”,y表示存储位置)

3,存储进哈希表

进入哈希表情况
一次添加成功哈希表规则上没有,第一次添加成功
多次添加成功出现冲突,调用equals方法与对应链表进行比较,比较到最后都是false时,创建新节点并存储数据,添加到链表末尾
不添加出现冲突,调用equals方法与对应链表进行比较,比较到最后都是ture时,表明重复了,不添加

结论1:哈希表添加速度快(不考虑冲突情况下。三步就完成了),

结论2: 数据唯一并且无序

小问题:为什么重写hashCode就一定要重写equals方法?

原因:当我们重写hashCode方法后,当发生存储数据进入哈希表发生冲突时,我们就需要equals方法进行“比较”,来决定数据是否重复,选择添加或者不添加。

哈希表查询数据

与哈希表添加数据相同,

1,计算哈希码,

2,根据哈希码计算出在哈希表中存储位置

3,查找哈希表

查找哈希表情况
一次查找刚刚好查找的值在哈希表链表前面第一个位置
多次查找查找的值不在哈希表链表前面第一个位置,不是目标,equals方法向下查找直到找到
找不到查找的值不在哈希表链表前面第一个位置,不是目标,equals方法向下查找也没有找到目标

哈希表面试题

hashCode方法和equals方法有什么作用?

hashCode:计算哈希码,是一个整数,通过哈希码可以计算出数据哈希表中的位置。

equals:当添加出现冲突是,通过equals进行比较,看数据是否存在,同样在查找中使用判断数据是否正确

各种类型如何获取哈希码?

int:取自身(23-->23) (看 Interger 源码 )

double: 不可以取整 (看 double 源码,通过内部方法计算获取整 

String: 通过字符串位置与编码值进行计算(例abc:(31*(31*(31*0*97)*98)*99)  :a:编码值97,

b:编码值98,c:编码值99)

 对象:对每一个对象的成员变量的哈希码,通过相加相乘进行计算(与字符串差不多)

为什么哈希码计算复杂?

哈希码相同则存储的内容相同,当哈希码复杂,哈希码相同概率减小就增加了哈希表的添加与查找速度。

如何减少冲突?

冲突是避免不了的,我们只能够减小冲突。

装填因子:哈希表的长度与表中记录数的长度的比例(表中记录数/哈希表长度

当装填因子达到0.5(一般情况下取0.5)的时候,可以对主数组进行扩容。

方法:链表地址法,开放地址法,再散列法,建立公共溢出区。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韶光不负

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值