关于hashmap,希望能够帮到你

这篇具有很好参考价值的文章主要介绍了关于hashmap,希望能够帮到你。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

介绍hashmap前先说一下关于的map知识


提示:以下是本篇文章正文内容,下面案例可供参考

一、Map的概念和场景

1.map的概念

Map是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。以前常见的
搜索方式有:

  1. 直接遍历,时间复杂度为O(N),元素如果比较多效率会非常慢
  2. 二分查找,时间复杂度为 ,但搜索前必须要求序列是有序的
    上述排序比较适合静态类型的查找,即一般不会对区间进行插入和删除操作了,而现实中的查找比如:
  3. 根据姓名查询考试成绩
  4. 通讯录,即根据姓名查询联系方式
  5. 不重复集合,即需要先搜索关键字是否已经在集合中
    可能在查找时进行一些插入和删除的操作,即动态查找,那上述两种方式就不太适合了,本节介绍的Map和Set是
    一种适合动态查找的集合容器。

2.模型

一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种。

1. 纯 key 模型

1.字典中找一个字
2.通讯录找名字

2. Key-Value 模型

1.统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>。
2.梁山好汉的绰号
而Map中存储的就是key-value的键值对,Set中只存储了Key。

二、Map的使用

关于hashmap,希望能够帮到你

1.关于Map的使用

Map是一个接口类,该类没有继承自Collection,该类中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复。

2. 关于Map.Entry<K, V>的说明

Map.Entry<K, V> 是Map内部实现的用来存放<key, value>键值对映射关系的内部类,该内部类中主要提供了<key, value>的获取,value的设置以及Key的比较方式。
三大方法:
关于hashmap,希望能够帮到你
注意:Map.Entry<K,V>并没有提供设置Key的方法

3. Map 的常用方法说明

关于hashmap,希望能够帮到你

注意:

  1. **Map是一个接口,不能直接实例化对象,**如果要实例化对象只能实例化其实现类TreeMap或者HashMap
  2. Map中存放键值对的Key是唯一的,value是可以重复的
  3. 在TreeMap中插入键值对时,key不能为空,否则就会抛NullPointerException异常,value可以为空。但
    是HashMap的key和value都可以为空。
  4. Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
  5. Map中的value可以全部分离出来,存储在Collection的任何一个子集合中加粗样式(value可能有重复)。
  6. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行
    重新插入。
  7. TreeMap和HashMap的区别
  8. 关于hashmap,希望能够帮到你
public static void TestMap(){
Map<String, String> m = new TreeMap<>();
// put(key, value):插入key-value的键值对
// 如果key不存在,会将key-value的键值对插入到map中,返回null
m.put("林冲", "豹子头");
m.put("鲁智深", "花和尚");
m.put("武松", "行者");
m.put("宋江", "及时雨");
String str = m.put("李逵", "黑旋风");
System.out.println(m.size());
System.out.println(m);
// put(key,value): 注意key不能为空,但是value可以为空
// key如果为空,会抛出空指针异常
//m.put(null, "花名");
str = m.put("无名", null);
System.out.println(m.size());
// put(key, value):
// 如果key存在,会使用value替换原来key所对应的value,返回旧value
str = m.put("李逵", "铁牛");
// get(key): 返回key所对应的value
// 如果key存在,返回key所对应的value
// 如果key不存在,返回null
System.out.println(m.get("鲁智深"));
System.out.println(m.get("史进"));
//GetOrDefault(): 如果key存在,返回与key所对应的value,如果key不存在,返回一个默认值
System.out.println(m.getOrDefault("李逵", "铁牛"));
System.out.println(m.getOrDefault("史进", "九纹龙"));
System.out.println(m.size());
//containKey(key):检测key是否包含在Map中,时间复杂度:O(logN)
// 按照红黑树的性质来进行查找
// 找到返回true,否则返回false
System.out.println(m.containsKey("林冲"));
System.out.println(m.containsKey("史进"));
// containValue(value): 检测value是否包含在Map中,时间复杂度: O(N)
// 找到返回true,否则返回false
System.out.println(m.containsValue("豹子头"));
System.out.println(m.containsValue("九纹龙"));
// 打印所有的key
// keySet是将map中的key防止在Set中返回的
for(String s : m.keySet()){
System.out.print(s + " ");
} S
ystem.out.println();
// 打印所有的value
// values()是将map中的value放在collect的一个集合中返回的
for(String s : m.values()){
System.out.print(s + " ");
} S
ystem.out.println();
// 打印所有的键值对
// entrySet(): 将Map中的键值对放在Set中返回了
for(Map.Entry<String, String> entry : m.entrySet()){
System.out.println(entry.getKey() + "--->" + entry.getValue());
} S
ystem.out.println();
}

三.hashmap

哈希函数方法:hash(key) = key%capacity
关于hashmap,希望能够帮到你

1.方法构造

public class HashBuck {
    static class Node{
        public int key;
        public int val;
        public Node next;
        public Node(int key,int val) {
            this.key = key;
            this.val = val;
        }
    }
    public Node []arr;
    public int usedsize;
    public HashBuck(){
        arr = new Node[10];
    }
    public void put(int key,int val){
        int index = key% arr.length;
        Node cur = arr[index];
        while(cur!=null){
            if (cur.key == key){
                cur.val = val;
                return;
            }
            cur = cur.next;
        }
        Node node = new Node(key, val);
        node.next = arr[index];
        arr[index] = node;
        usedsize++;
    }
    public void resize(){
        Node []newarr = new Node[2* arr.length];
        for (int i = 0; i < arr.length; i++) {
            Node cur = arr[i];
        }
    }
    public double calculateLoadFactor(){
        return usedsize*1.0/arr.length;
    }
    public int get(int key){
        int index = key% arr.length;
        Node cur = arr[index];
        while (cur!=null){
            if (cur.key == key){
                return cur.val;
            }
            cur = cur.next;
        }
        return -1;
    }

测试方法

HashBuck hashBuck = new HashBuck();
        hashBuck.put(10, 20);
        hashBuck.put(30, 5);
        hashBuck.put(43, 6);
        hashBuck.put(50, 7);
        Integer val = hashBuck.get(10);
        System.out.println(val);

关于hashmap,希望能够帮到你
思路类似于这张图,put方法

2 冲突-概念

对于两个数据元素的关键字 和 (i != j),有 != ,但有:Hash( ) == Hash( ),即:不同关键字通过相同哈
希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞
把具有不同关键码而具有相同哈希地址的数据元素称为“同义词”。

3. 冲突-避免-哈希函数设计

引起哈希冲突的一个原因可能是:哈希函数设计不够合理。 哈希函数设计原则:
1.哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0到m-1之间
2.哈希函数计算出来的地址能均匀分布在整个空间中
3.哈希函数应该比较简单
常见哈希函数

  1. 直接定制法–(常用)
    取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B 优点:简单、均匀 缺点:需要事先知道关
    键字的分布情况 使用场景:适合查找比较小且连续的情况 面试题:字符串中第一个只出现一次字符
  2. 除留余数法–(常用)
    设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:
    Hash(key) = key% p(p<=m),将关键码转换成哈希地址
  3. 平方取中法
    假设关键字为1234,对它平方就是1522756,抽取中间的3位227作为哈希地址; 再比如关键字为4321,对
    它平方就是18671041,抽取中间的3位671(或710)作为哈希地址 平方取中法比较适合:不知道关键字的分布,而位数又不是很大的情况
  4. 折叠法–
  5. 随机数法–
    选择一个随机函数,取关键字的随机函数值为它的哈希地址,即H(key) = random(key),其中random为随机数
    函数。
    通常应用于关键字长度不等时采用此法
  6. 数学分析法–
    设有n个d位数,每一位可能有r种不同的符号,这r种不同的符号在各位上出现的频率不一定相同,可能在某
    些位上分布比较均匀,每种符号出现的机会均等,在某些位上分布不均匀只有某几种符号经常出现。可根据
    散列表的大小,选择其中各种符号分布均匀的若干位作为散列地址。例如:
    假设要存储某家公司员工登记表,如果用手机号作为关键字,那么极有可能前7位都是 相同的,那么我们可以
    选择后面的四位作为散列地址,如果这样的抽取工作还容易出现 冲突,还可以对抽取出来的数字进行反转(如1234改成4321)、右环位移(如1234改成4123)、左环移位、前两数与后两数叠加(如1234改成12+34=46)等方法
    数字分析法通常适合处理关键字位数比较大的情况,如果事先知道关键字的分布且关键字的若干位分布较均
    匀的情况
    注意:哈希函数设计的越精妙,产生哈希冲突的可能性就越低,但是无法避免哈希冲突

4.开散列和闭散列

1.闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去。
1.1. 线性探测
比如上面的场景,现在需要插入元素44,先通过哈希函数计算哈希地址,下标为4,因此44理论上应该插在该位置,但是该位置已经放了值为4的元素,即发生哈希冲突。
线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。
插入:
通过哈希函数获取待插入元素在哈希表中的位置
如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探测找到
下一个空位置,插入新元素。
关于hashmap,希望能够帮到你
2.开散列/哈系桶:
开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。
思路:关于hashmap,希望能够帮到你

每一次哈希后指向数组下标的值,然后桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。
开散列,可以认为是把一个在大集合中的搜索问题转化为在小集合中做搜索了。

public class HashBuck {
    static class Node{
        public int key;
        public int val;
        public Node next;
        public Node(int key,int val) {
            this.key = key;
            this.val = val;
        }
    }
    public Node []arr;
    public int usedsize;
    public HashBuck(){
        arr = new Node[10];
    }
    public void put(int key,int val){
        int index = key% arr.length;
        Node cur = arr[index];
        while(cur!=null){
            if (cur.key == key){
                cur.val = val;
                return;
            }
            cur = cur.next;
        }
        Node node = new Node(key, val);
        node.next = arr[index];
        arr[index] = node;
        usedsize++;
    }
    public void resize(){
        Node []newarr = new Node[2* arr.length];
        for (int i = 0; i < arr.length; i++) {
            Node cur = arr[i];
        }
    }
    public double calculateLoadFactor(){
        return usedsize*1.0/arr.length;
    }
    public int get(int key){
        int index = key% arr.length;
        Node cur = arr[index];
        while (cur!=null){
            if (cur.key == key){
                return cur.val;
            }
            cur = cur.next;
        }
        return -1;
    }

总结

好了,今天的博客到这里就结束了,欢迎各位在评论区讨论,求个一键三连。文章来源地址https://www.toymoban.com/news/detail-439299.html

到了这里,关于关于hashmap,希望能够帮到你的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 迟到的秋招经验分享贴,希望能帮到大家

          由于毕业之前各种各样的事情,去年的秋招经验一直没有整理分享,现在趁周末尽可能多的将之前的资料整理一下,方便各位找工作的师弟师妹们参考,也算将自己的一点点经验分享给大家,希望能帮到大家。 (1) 一定要学会抱团取暖 。       各位同学身边肯定

    2023年04月08日
    浏览(38)
  • 无代码可视化开源爬虫软件EasySpider,希望能帮到大家

    EasySpider是一款可视化爬虫软件,此软件可以让大家使用图形化界面,无代码可视化的设计和执行爬虫任务。只需要在网页上选择自己想要爬的内容并根据提示框操作即可完成爬虫设计和执行。同时软件还可以以Web服务的方式进行API调用,从而可以很方便的嵌入到其他系统中。

    2024年02月10日
    浏览(39)
  • ChatGPT Plus价格太贵,可以约上三五知己一起上车体验一下,这个项目就能帮到你

    对于想体验 ChatGPT PLus 的小伙伴,可能觉得自己一个人一个月花费20美元,相对于人民币每月137多,确实是一个不少的开支,如果,几个人合作一个账号,这样负担就减少了。刚好,最近逛 github 发现刚好有一个这样的项目。 ChatGPT Web Share (简称 CWS) 的目的是「共享」一个 Cha

    2023年04月20日
    浏览(42)
  • 2022最新VMware虚拟机下载·Linux系统装配·镜像文件下载·联网使用一条龙--------希望可以帮到你们

    小新一枚,请前辈赐教,友友批评,这是我小小的经验,如有纰漏,还望海涵 前期工作准备: 1.下好VMware安装包和镜像文件(Windows11建议vm17兼容) 2.在D或者E盘建好文件夹专门储存虚拟机相关文件 3.做好多次尝试的准备,慢慢来,只要你成功了就超过很多人了 其余省略的步

    2024年02月06日
    浏览(40)
  • 1.前言和介绍

    从零学习算法部署-TensorRT篇 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记 本次主要是对课程的内容和所需环境做一个简要的介绍 课程大纲可看下面的思维导图 本课程以 TensorRT 和 PyTor

    2024年02月13日
    浏览(37)
  • WebGL前言——WebGL相关介绍

    第一讲内容主要介绍WebGL技术和相应的硬件基础部分,在初级课程和中级课程的基础上,将技术和硬件基础进行串联,能够对WebGL从产生到消亡有深刻全面的理解。同时还介绍WebGL大家在初级课程和中级课程中的一些常见错误以及错误调试的办法。 先热身一下吧,看个问题:如

    2023年04月08日
    浏览(33)
  • 【RabbitMQ教程】前言 —— 中间件介绍

                                                                       💧 【 R a b b i t M Q 教程】前言——中间件介绍 color{#FF1493}{【RabbitMQ教程】前言 —— 中间件介绍} 【 R abbi tMQ 教程】前言 —— 中间件介绍 💧           🌷 仰望天空,妳

    2024年02月08日
    浏览(60)
  • Rx.NET in Action 中文介绍 前言及序言

    目标 可选方式 Rx 处理器(Operator) 创建 Observable Creating Observables 直接创建 By explicit logic Create Defer 根据范围创建 By specification Range Repeat Generate Timer Interval Return 使用预设 Predefined primitives Throw Never Empty 从其他类型创建 From other types FromEventPattern FromEvent FromTask FromAsync 变换 Transform

    2024年02月13日
    浏览(40)
  • HashMap原理详解及常用API介绍

    如果你准备面试Java后端方向的工程师,那么HashMap可以说是面试中的重中之重,你去10家公司面试,可能8家公司都会会问道。所以可见HashMap相关的知识点对于我们面试来说有多么重要,接下来就让我们走进HashMap的大门吧! HashMap是Java当中一种数据结构,是一个用于存储Key-V

    2024年02月16日
    浏览(27)
  • 学单片机前先学什么?

    在开始前我有一些资料,是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!先学c语言和数字电路 这里默认你说的单片机是51单片机,通过你的问题,我猜你的单片

    2024年01月24日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包