HashMap原理

在弄清楚HashMap的原理之前,先要了解以下几点:

1.哈希算法

	哈希(Hash),又可以称为散列

概述: 哈希算法可以将任意长度的消息M,映射成为一个长度较短,长度固定的值H(M),称H(M)为哈希值,散列值,或者消息摘要(Message Digest),它的加密是单向的,不可逆的,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程

例如: 将字符串"abc"通过哈希算法运算可以得到一个定长的"lovejava"(不同的Hash算法计算的值不同),“abc"和"lovejava"就形成了一种映射关系,只要知道了"abc”,就可以通过哈希函数找到值"lovejava",大大提高了查找的性能

用途:
1.数字签名
2.生成文件的唯一标识
3.数据校验
4.哈希函数:常见的hash算法有CRC,SHA1,SHA256,MD5等等,函数表达式为:h=H(m)

2.哈希冲突

	哈希冲突,又称为哈希碰撞

哈希算法有一种常用的计算方法,就是取模运算

这里用一个简单的例子:

  • 通过哈希取模运算,计算一串序列 [1,2,3,4,5,6] 的哈希值

    过程就是,用序列里的每个数,对一个常数取模,将取模运算后的结果,作为数组索引,这里假设常数为5
    1 % 5 = 1
    2 % 5 = 2
    3 % 5 = 3
    4 % 5 = 4
    5 % 5 = 0
    6 % 5 = 1
    这时,我们就发现问题了,1和6经过哈希取模运算之后,计算出来的哈希值是都是1,这种情况就称为哈希冲突(两个不同的数据计算后的结果一样)

    Java中的说法就是: 两个不同对象的hashCode值都是相同的

显然,出现这种情况对我们是不利的,那么如何避免哈希冲突?
1.开放地址法

		这种方法的原理大概就是,在发现发生了哈希碰撞之后,再通N次Hash运算,计算出一个hash值,在
数组中的体现就是,会找到数组中元素为空的位置,作为再Hash的结果

2.拉链法

	(1)将所有哈希地址相同的都链接在同一个链表中,因而查找、插入和删除在同一个链中进行
	(2)链地址法适用于经常进行插入和删除的情况。
  • Java中的HashMap使用的就是拉链法

3.哈希表

	Java的HashMap的数据结构正是哈希表

在这里插入图片描述
哈希表在Java中就是数组 + 链表 + 红黑树(JDK1.8后)

HashMap存储元素过程(此处涉及到了hashCodeequals方法的知识)

先计算存入元素的hashCode值
判断该hashCode值是否与数组中元素的hashCode值重复
无重复时,证明在数组中没有相同的元素,那么直接存入对应的数组下标中
有重复时,找到重复元素上的链表(如果有的话),依次与该链表的每个元素进行equals方法进行判断
只要有一个元素进行equals方法比较结果为true,那么就可以证明是相同的元素,不将该元素存入

通过以上的方法,HashMap就能能保证Key是惟一的,每个链表的长度到达8之后,会自动变成红黑树,因为链表是查询慢的。链表的每个结点只存储了直接后继结点的地址值,所以,再链表中查找元素得从表头开始遍历,时间复杂度为O(n),所以链表长度过长会影响HashMap的效率,所以引入红黑树来保证效率

	我们再从Java集合的框架去看,List是有序的,可重复的,而Set和Map是无序的,不可重复的
	如何保证集合的元素不重复?自然是Object的equals方法
	假设Set和Map和List使用的都是数组,那么当数组中有10000个元素时,在插入10001个元素的时侯,就
	要对10000个元素进行equals方法比较,性能低下,而采用哈希表之后,再保证元素唯一的这点上,效率要
	高很多
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值