数据结构:哈希表原理以及面试中的常见考点

点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

日英文

Don't worry if you're still single. God's looking at you right now, saying:"I'm saving this girl for someone special." 

如果你还是单身的话,别着急。上帝正在看着你说:“我要给这个女孩留一个特别的!”

每日掏心话

当时光划过心弦,每一阵痛楚都是一点成熟。原来长大,是一种代价。而人生,就是一种交换。
责编:乐乐 | 来自:blog.csdn.net/m0_55221239/article/details/1145324039

编程技术圈(ID:study_tech)第 1254 次推文

往日回顾:再见了!收费的XShell,这次我力挺这款免费的国产良心工具。。。

     

   正文   

首先得看java最基本的两种数据结构,数组和链表的区别:

而哈希表的出现是为了解决链表访问不快速的弱点,为了达到这一个目的:

哈希表中有一个哈希函数(散列函数)。即构建一个确定的映射,它能把关键字映射到一个唯一的存储位置。这种映射应该是我们可以进行计算的。已知关键字,我们应该能算出其地址;反之,已知地址,我们可以检索到对应的关键字。一旦建立起这种关系,那么给定关键字,我就能直接利用这个映射(即所谓的哈希函数)直接算出其地址并寻址。这可大大缩减确定关键字存储位置所花的时间。

HashMap和HashSet的区别

HashSet是通过HashMap来实现的,HashMap的输入参数有Key、Value两个组成,在实现HashSet的时候,保持HashMap的Value为常量,相当于在HashMap中只对Key对象进行处理。

HashMap的底层是一个数组结构,数组中的每一项对应了一个链表,这种结构称“链表散列”的数据结构,即数组和链表的结合体;也叫散列表、哈希表。

想要了解HashMap和HashSet这样两个不同存储结构的区别,就得熟知他们的存储过程:

HashMap存储对象的过程
  • 对HashMap的Key调用hashCode()方法,返回int值,即对应的hashCode;

  • 把此hashCode作为哈希表的索引,查找哈希表的相应位置,若当前位置内容为NULL,则把HashMap的Key、Value包装成Entry数组,放入当前位置;

  • 若当前位置内容不为空,则继续查找当前索引处存放的链表,利用equals方法,找到Key相同的Entry数组,则用当前Value去替换旧的Value;

  • 若未找到与当前Key值相同的对象,则把当前位置的链表后移(Entry数组持有一个指向下一个元素的引用),把新的Entry数组放到链表表头;

  • 搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。

HashSet存储对象的过程
  • 往HashSet添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,

  • 然后通过元素 的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置,存储时会出现两种情况:

    • 情况1:如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。

    • 情况2:如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素允许添加。

小结

HashSet和HashMap的区别

常见考点

它的主要考点有:

  • 是否会灵活的使用哈希表解决问题

  • 是否熟练掌握哈希表的基本原理

  • 哈希冲突解决方法

小提示:
  • HashSet实现了Set接口,其内部不允许出现重复的值,如果我们将一个对象存入HashSet,必须重写equals()和hashCode()方法,这样才能确保集合中不存在同一个元素。HashSet的内部是无序的,因此不能使用 hashset.get(index) 来获取元素。

  • HashMap实现了Map接口,其内容是键值对的映射(key->value),不允许出现相同的键(key)。在查询的时候会根据给出的键来查询对应的值。

  • 我们可以认为,HashSet和HashMap增查操作的时间复杂度都是常数级的。推荐:250期面试题汇总

哈希冲突解决方法

冲突(Collision),是说两个不同的 key 经过哈希函数的计算后,得到了两个相同的值。解决冲突的方法,主要有两种:

  • 开散列法(Open Hashing)。是指哈希表所基于的数组中,每个位置是一个 Linked List 的头结点。这样冲突的 <key,value> 二元组,就都放在同一个链表中。

  • 闭散列法(Closed Hashing)是指在发生冲突的时候,后来的元素,往下一个位置去找空位。

哈希表的扩容

哈希表容量的大小在一开始是不确定的。如果哈希表存储的元素太多(如超过容量的30%),我们应该将哈希表容量扩大一倍,并将所有的哈希值重新安排。

扩展:HashFunction的实现
public class Solution {
    /**
     * @param key: A string you should hash
     * @param HASH_SIZE: An integer
     * @return: An integer
     */
    public int hashCode(char[] key, int HASH_SIZE) {
        // write your code here
        long ans = 0;
        for(int i = 0; i < key.length; i++){
            ans = (ans * 33 + (int)(key[i])) % HASH_SIZE;
        }
        return (int)(ans);
    }
}
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
欢迎加入后端架构师交流群,在后台回复“学习”即可。
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结。别找了,想获取史上最简单的Java大厂面试题学习资料扫下方二维码回复「面试」就好了猜你还想看阿里、腾讯、百度、华为、京东最新面试题汇集再见 Maven,我用它!!!
这几个SpringBoot前后端分离项目(附源码),改改就能换钱。。。
7年员工因拒绝钉钉打卡被开除,索赔近60万,终审判决来了!
嘿,你在看吗?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值