【java数据结构】HashMap和HashSet

目录

一.认识哈希表:

1.1什么是哈希表?

1.2哈希表的表示: 

1.3常见哈希函数:

 二.认识HashMap和HashSet:

2.1关于Map.Entry的说明:,>

2.2Map常用方法说明:

2.3HashMap的使用案例:

2.4Set常见方法说明:

 2.5HashSet使用案例:

源码:


一.认识哈希表:

1.1什么是哈希表?

之前的学习中,如果我们要查找一个元素,肯定是要经过比较的,那有没有一种办法,可以不用经过比较,直接就能拿到呢?

如果我们能构造一种存储结构,通过一种函数 (hashFunc) 使元素的存储位置与函数得出的关键码之间能够建立一一映射的关系,那么在查找某个元素的时候,就能通过这个函数来很快的找到该元素所在的位置。

这种函数就叫做哈希(散列)函数,上述所说构造出来的结构,叫做哈希表或者称为散列表。

 哈希表简介:

哈希表(Hash Table):也叫做散列表。是根据关键码值(Key Value)直接进行访问的数据结构。哈希表通过「键 key 」和「映射函数 Hash(key) 」计算出对应的「值 value」,把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做「哈希函数(散列函数)」,存放记录的数组叫做「哈希表(散列表)」。

1.2哈希表的表示: 

 举个栗子:为了记录一个班的学生的信息,分别包括学号和姓名。我们就可以用哈希表(数组加链表)来记录,这里学号(关键值key)通过哈希函数得到一个数组下标,这个下标就是这个学生信息存放在对应数组中的位置,同时学生的信息(姓名和学号)叫做键值对,又称作Entry

 使用方法:

  • 向哈希表中插入一个关键码值:哈希函数决定该关键字的对应值应该存放到表中的哪个区块,并将对应值存放到该区块中。
  • 在哈希表中搜索一个关键码值:使用相同的哈希函数从哈希表中查找对应的区块,并在特定的区块搜索该关键字对应的值。
  • 实现哈希表: 数组+链表 或者  数组+二叉树

1.3常见哈希函数:

  • 直接定值法--(常用):取关键字的某个线性函数为散列地址:HashKey= A*Key + B 优点:简单、均匀 缺点:需要事先知道关 键字的分布情况 使用场景:适合查找比较小且连续的情况
  • . 除留余数法--(常用) : 
    设散列表中允许的 地址数为 m ,取一个不大于 m ,但最接近或者等于 m 的质数 p 作为除数,按照哈希函数: Hash(key) = key% p(p<=m), 将关键码转换成哈希地址
  • 例如:

 二.认识HashMap和HashSet:

 HashMap和HashSet是Java集合框架中的两个常用类,它们都实现了Set接口,但在实现原理和用途上有一些区别。

  • HashMap:HashMap是基于哈希表的实现,它使用键值对(key-value)的方式存储数据HashMap允许存储null键和null值,并且可以存储重复的值,但不允许重复的键。HashMap内部使用哈希函数将键映射到哈希表的索引位置,以实现快速的插入、删除和查找操作。HashMap的查找操作是通过键来进行的,因此可以根据键快速地获取对应的值。
  • HashSet:HashSet也是基于哈希表的实现,它存储唯一的元素,不允许重复值HashSet允许存储null值,但只能存储一个null元素。HashSet内部使用哈希函数将元素映射到哈希表的索引位置,以实现快速的插入、删除和查找操作。HashSet的查找操作是通过元素来进行的,因此可以根据元素快速地判断是否存在于集合中。

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

Map.Entry<K, V> Map 内部实现的用来存放 <key, value> 键值对映射关系的内部类 ,该内部类中主要提供了 <key, value>的获取, value 的设置以及 Key 的比较方式。
方法解释
K getKey ()
返回 entry 中的 key
V getValue ()
返回 entry 中的 value
V setValue(V value)
将键值对中的 value 替换为指定 value
注意: Map.Entry<K,V> 并没有提供设置 Key 的方法

2.2Map常用方法说明:

2.3HashMap的使用案例:

基础操作:

Map<String, String> m = new HashMap<>();// put(key, value):插入key-value的键值对// 如果key不存在,会将key-value的键值对插入到map中,返回nullm.put("林冲", "豹子头");m.put("鲁智深", "花和尚");m.put("武松", "行者");m.put("宋江", "及时雨");String str = m.put("李逵", "黑旋风");m.remove("武松","行者");System.out.println("map的大小(size):" + m.size());System.out.println("map中的元素:" + m);System.out.println("这时str为空: " + str);// put(key,value): 注意key不能为空,但是value可以为空m.put("无名", null);      // key如果为空,会抛出空指针异常System.out.println("当前map的大小: " + m.size());str = m.put("李逵", "铁牛");System.out.println("返回旧的value值: " + str);System.out.println("得到Key所对应的value值: " + m.get("李逵"));

运行结果:

GetOrDefault()和containKey(key):
//GetOrDefault(): 如果key存在,返回与key所对应的value,如果key不存在,返回一个默认值System.out.println("=========================================");System.out.println("李逵存在,返回key对应的value: " + m.getOrDefault("李逵", "牛牛"));System.out.println("史进不存在,返回一个默认值: " + m.getOrDefault("史进", "九龙纹"));System.out.println("=========================================");//containKey(key):检测key是否包含在Map中,时间复杂度:O(logN)System.out.println(m.containsValue("豹子头"));System.out.println(m.containsValue("行者"));

运行结果:

三种遍历方法:

System.out.println("-----key ------value -----Entry的遍历方法:----------");System.out.println("key遍历:  ");for (String s : m.keySet()) {System.out.print(s + " ");}System.out.println();System.out.println("value遍历:  ");for (String s : m.values()) {System.out.print(s + " ");}System.out.println();System.out.println("entry遍历: ");for (Map.Entry<String, String> entry : m.entrySet()) {System.out.println(entry.getKey() + "--->" + entry.getValue());}

运行结果:

注意:

1. Map 是一个接口,不能直接实例化对象 ,如果 要实例化对象只能实例化其实现类 TreeMap 或者 HashMap
2. Map 中存放键值对的 Key 是唯一的, value 是可以重复的
3. Map 中的 Key 可以全部分离出来,存储到 Set 来进行访问 ( 因为 Key 不能重复 )
4. Map 中的 value 可以全部分离出来,存储在 Collection 的任何一个子集合中 (value 可能有重复 )
5. Map 中键值对的 Key 不能直接修改, value 可以修改,如果要修改 key ,只能先将该 key 删除掉,然后再来进行重新插入。

2.4Set常见方法说明:

方法解释
boolean add (E e)
添加元素,但重复元素不会被添加成功
void clear ()
清空集合
boolean contains (Object o)
判断 o 是否在集合中
Iterator<E> iterator ()
返回迭代器
boolean remove (Object o)
删除集合中的 o
int size()
返回set中元素的个数
boolean isEmpty()
检测 set 是否为空,空返回 true ,否则返回 false
Object[] toArray()
set 中的元素转换为数组返回
boolean containsAll(Collection<?> c)
集合 c 中的元素是否在 set 中全部存在,是返回 true ,否则返回
false
boolean addAll(Collection<? extends
E> c)
将集合 c 中的元素添加到 set 中,可以达到去重的效果

 2.5HashSet使用案例:

System.out.println("================HashSet===============");Set<String> s = new HashSet<>();boolean isIn = s.add("apple");s.add("orange");s.add("peach");s.add("banana");System.out.println(s.size());System.out.println(s);System.out.println("add(key): 如果key不存在,则插入,返回true: " + isIn);isIn = s.add("apple");System.out.println("add(key):如果key存在,则返回false: " + isIn);// contains(key): 如果key存在,返回true,否则返回falseSystem.out.println(s.contains("apple"));System.out.println(s.contains("watermelen"));s.remove("apple");// remove(key): key存在,删除成功返回trueSystem.out.println(s);// key不存在,删除失败返回false , key为空,System.out.println("迭代器遍历:");Iterator<String> it = s.iterator();while (it.hasNext()) {System.out.print(it.next() + " ");}

运行结果:

注意:

1. Set 是继承自Collection的一个接口类
2. Set 中只存储了 key ,并且要求 key 一定要唯一
3. Set 的底层是使用 Map 来实现的,其使用 key Object 的一个默认对象作为键值对插入到 Map 中的
4. 实现 Set 接口的常用类有 TreeSet HashSet ,还有一个 LinkedHashSet LinkedHashSet 是在 HashSet 的基础上维护了一个双向链表来记录元素的插入次序。
5. Set 中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
6. Set 中不能插入nullkey

源码:

import java.util.TreeMap;
import java.util.Set;
import java.util.Map;public class Test1 {public static void main(String[] args) {Map<String, String> m = new HashMap<>();// put(key, value):插入key-value的键值对// 如果key不存在,会将key-value的键值对插入到map中,返回nullm.put("林冲", "豹子头");m.put("鲁智深", "花和尚");m.put("武松", "行者");m.put("宋江", "及时雨");String str = m.put("李逵", "黑旋风");m.remove("武松","行者");System.out.println("map的大小(size):" + m.size());System.out.println("map中的元素:" + m);System.out.println("这时str为空: " + str);// put(key,value): 注意key不能为空,但是value可以为空m.put("无名", null);      // key如果为空,会抛出空指针异常System.out.println("当前map的大小: " + m.size());str = m.put("李逵", "铁牛");System.out.println("返回旧的value值: " + str);System.out.println("得到Key所对应的value值: " + m.get("李逵"));//GetOrDefault(): 如果key存在,返回与key所对应的value,如果key不存在,返回一个默认值System.out.println("=========================================");System.out.println("李逵存在,返回key对应的value: " + m.getOrDefault("李逵", "牛牛"));System.out.println("史进不存在,返回一个默认值: " + m.getOrDefault("史进", "九龙纹"));System.out.println("=========================================");//containKey(key):检测key是否包含在Map中,时间复杂度:O(logN)System.out.println(m.containsValue("豹子头"));System.out.println(m.containsValue("行者"));System.out.println("-----key ------value -----Entry的遍历方法:----------");System.out.println("key遍历:  ");for (String s : m.keySet()) {System.out.print(s + " ");}System.out.println();System.out.println("value遍历:  ");for (String s : m.values()) {System.out.print(s + " ");}System.out.println();System.out.println("entry遍历: ");for (Map.Entry<String, String> entry : m.entrySet()) {System.out.println(entry.getKey() + "--->" + entry.getValue());}System.out.println("================HashSet===============");Set<String> s = new HashSet<>();boolean isIn = s.add("apple");s.add("orange");s.add("peach");s.add("banana");System.out.println(s.size());System.out.println(s);System.out.println("add(key): 如果key不存在,则插入,返回true: " + isIn);isIn = s.add("apple");System.out.println("add(key):如果key存在,则返回false: " + isIn);// contains(key): 如果key存在,返回true,否则返回falseSystem.out.println(s.contains("apple"));System.out.println(s.contains("watermelen"));s.remove("apple");// remove(key): key存在,删除成功返回trueSystem.out.println(s);// key不存在,删除失败返回false , key为空,System.out.println("迭代器遍历:");Iterator<String> it = s.iterator();while (it.hasNext()) {System.out.print(it.next() + " ");}}
}

结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固自己的知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739832.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K 个一组翻转链表

题目&#xff1a; struct ListNode{int val;ListNode* next;ListNode(): val(0), next(nullptr) {}ListNode(int _val): val(_val), next(nullptr) {}ListNode(int _val, ListNode* _next): val(_val), next(_next) {} };class Solution { public:ListNode* reverseKGroup(Li…

555经典电路

1、555介绍&#xff1a; 555 定时器是一种模拟和数字功能相结合的中规模集成器件。一般用双极性工艺制作的称为 555&#xff0c;用 CMOS 工艺制作的称为 7555&#xff0c;除单定时器外&#xff0c;还有对应的双定时器 556/7556。555 定时器的电源电压范围宽&#xff0c;可在 4…

如何在Linux使用docker安装Plik并实现无公网ip上传下载内网存储的文件资源

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&…

屏蔽百度热搜榜

步骤&#xff1a; 打开谷歌应用商店&#xff1a;https://chrome.google.com/webstore/category/extensions?hlzh-CN 安装Adblock Plus插件 然后,哪里不爽点哪里(N多次重复点)! 世界清净了!

机器学习--循环神经网络(RNN)3

本篇文章结合具体的例子来介绍一下LSTM运算方式以及原理。请结合上篇文章的介绍食用。 一、具体例子 如上图所示&#xff0c;网络里面只有一个 LSTM 的单元&#xff0c;输入都是三维的向量&#xff0c;输出都是一维的输出。 这三维的向量跟输出还有记忆元的关系是这样的。 假设…

深度学习:如何面对隐私和安全方面的挑战

深度学习技术的广泛应用推动了人工智能的快速发展&#xff0c;但同时也引发了关于隐私和安全的深层次担忧。如何在保护用户隐私的同时实现高效的模型训练和推理&#xff0c;是深度学习领域亟待解决的问题。差分隐私、联邦学习等技术的出现&#xff0c;为这一挑战提供了可能的解…

k8s-生产级的k8s高可用(2) 25

部署containerd k8s2、k8s3、k8s4在配置前需要重置节点&#xff08;reset&#xff09;在上一章已完成 禁用所有节点docker和cri-docker服务 所有节点清除iptables规则 重置后全部节点重启 由于之前部署过docker&#xff0c;因此containerd默认已安装 修改配置 启动containe…

嵌入式工资为啥比纯软工资低那么多?

嵌入式工资为啥比纯软工资低那么多&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&…

爬虫技术之正则提取静态页面数据

第一天 简单示例 在爬虫过程中&#xff0c;我们获取到了页面之后&#xff0c;通常需要做的就是解析数据&#xff0c;将数据持久化到数据库为我所用。如何又快又准确得提取有效数据&#xff1f;这是一门技术&#xff0c;看了我的博客之前可能略有难度&#xff0c;但各位大师看…

redis源码分析

是什么 是基于内存(而不是磁盘)的kv(而不是关系型mysql那种)数据库&#xff0c;通过空间换时间 源码分析 跳表skiplist 假设你有个有序链表&#xff0c;你想看某个特定的值是否出现在这个链表中&#xff0c;那你是不是只能遍历一次链表才能知道&#xff0c;时间复杂度为O(n…

Postman环境变量全局变量设置(详解版)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在公司中&#xff0c;一般会存在开发环境、测试环境、线上环境等…

找不到mfc140u.dll怎么办?修复缺失mfc140u.dll的多种方案分享

mfc140u.dll文件是一个重要的动态链接库文件&#xff0c;它在Windows操作系统中发挥着关键的作用。由于各种原因&#xff0c;例如应用程序冲突或系统错误等&#xff0c;mfc140u.dll文件有时会出现丢失的情况。一旦发生这种问题&#xff0c;运行依赖此文件的应用程序将无法正常启…

力扣刷题日记——L724. 寻找数组的中心下标

1. 前言 今天是力扣刷题日记的第二天&#xff0c;今天依旧是一道简单题啊&#xff0c;慢慢来&#xff0c;先看看题目是什么吧。 2. 题目描述 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和…

JSP中间件漏洞

jsp的注入最难挖 另外3个好挖 struts2 url有action 就代表是struts2 用漏洞利用工具 下面之这两个一般都可以用工具扫一下 、 有些网站看起来没有 action实际上我们提交了 我们的账号和密码 之后就有了 工具包是下面 这些 github上面也有 用法就是如下图 把url放进去就…

整数和浮点数在内存中储存的形式

整数 整数的二进制表示法有三种&#xff0c;即原码、反码、补码。 三种表示方式均有符号位和数值位 符号位位于数值位最高位的那一位&#xff0c;分别用0和1表示&#xff0c;0表示正数&#xff0c;1表示负数。 数值位&#xff0c;除最高位的那一位外其他都是数值位。 正整数…

续篇:展开聊下 state 与 渲染树中位置的关系

&#x1f43e; 上篇的结尾处&#xff0c;提到了 > 为了提升性能&#xff0c; React 仅在渲染之间 存在差异 时才会更改 DOM 节点。 本篇&#xff0c;✓ &#x1f1e8;&#x1f1f3; 展开聊下 state 与 渲染树中位置的关系 &#x1f4e2;&#x1f4e2;&#x1f4e2; 状态与…

GIS瓦片3-WMTS瓦片

介绍 WMTS( Web Map Tile Service)切片地图Web服务&#xff08;OpenGIS Web Map Tile Service&#xff09;当前最新版本是1.0.0。WMTS标准定义了一些操作&#xff0c;这些操作允许用户访问切片地图。WMTS可能是OGC首个支持RESTful访问的服务标准。 WMTS提供了一种采用预定义图…

Vue2利用创建a标签实现下载本地静态文件到本地电脑上的功能

最近PC项目遇到一个需求&#xff0c;那就是需要前端下载前端代码包里的前端文件到本地&#xff0c;并且可以给下载下来的文件名指定任意的文件名&#xff0c;如下图所示&#xff0c;在前端代码里public里的statics里有个静态文件zswj.pem&#xff0c;页面上有个下载按钮&#x…

CPU设计实战-协处理器访问指令的实现

目录 一 协处理器的作用与功能 1.计数寄存器和比较寄存器 2.Status寄存器 3.Cause寄存器(标号为13) 4.EPC寄存器(标号为14) 5.PRId寄存器(标号为15) 6.Config 寄存器(标号为16)-配置寄存器 二 协处理器的实现 三 协处理器访问指令说明 四 具体实现 1.译码阶段 2.执行…

初阶数据结构之---堆的应用(堆排序和topk问题)

引言 上篇博客讲到了堆是什么&#xff0c;以及堆的基本创建和实现&#xff0c;这次我们再来对堆这个数据结构更进一步的深入&#xff0c;将讲到的内容包括&#xff1a;向下调整建堆&#xff0c;建堆的复杂度计算&#xff0c;堆排序和topk问题。话不多说&#xff0c;开启我们今…