【数据结构】Map的使用与注意事项

简介: 【数据结构】Map的使用与注意事项

概念

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

  1. 直接遍历,时间复杂度为 O ( N ) O(N) O(N),元素如果比较多效率会非常慢
  2. 二分查找,时间复杂度为 O ( l o g N ) O(logN) O(logN),但搜索前必须要求序列是有序的

上述排序比较适合静态类型的查找,即一般不会对区间进行插入和删除操作了,而现实中的查找比如:

  1. 根据姓名查询考试成绩
  2. 通讯录,即根据姓名查询联系方式
  3. 不重复集合,即需要先搜索关键字是否已经在集合中

可能在查找时进行一些插入和删除的操作,即动态查找,那上述两种方式就不太适合了,本节介绍的 MapSet 是一种适合动态查找的集合容器。

模型

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

  1. key模型,比如:
  • 有一个英文词典,快速查找一个单词是否在词典中
  • 快速查找某个名字在不在通讯录中
  1. Key-Value模型,比如:
  • 统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>
  • 梁山好汉的江湖绰号:每个好汉都有自己的江湖绰号

Map 中存储的就是 key-value 的键值对,Set 中只存储了 Key

Map 的使用

MapSet 主要用于搜索

  • TreeSetTreeMap 底层就是一颗二叉搜索树==>红黑树
方法 解释
V get(Object key) 返回 key 对应的 value
V getOrDefault(Object key, V defaultValue) 返回 key 对应的 value,key 不存在,返回默认值
V put(K key, V value) 设置 key 对应的 value
V remove(Object key) 删除 key 对应的映射关系
Set keySet() 返回所有 key 的不重复集合
Collection values() 返回所有 value 的可重复集合
Set> entrySet() 返回所有的 key-value 映射关系
boolean containsKey(Object key) 判断是否包含 key
boolean containsValue(Object value) 判断是否包含 value

put() 和 get()

Map<String,String> map = new TreeMap<>();  
map.put("及时雨","松江");  
map.put("齐天大圣","孙悟空");  
  
String val = map.get("齐天大圣");  
String val2 = map.get("孙悟空");  
System.out.println(val);  
System.out.println(val2);
/*
运行结果:
孙悟空
null
*/
  • put 的时候是有顺序的,前面的是 Key ,后面的是 Value
  • 进行 get 的时候是返回 Key 所对应的 Value,而不能返回 Value 所对应的 Key

getOrDefault()

当没有找到 Key 所对应的 Value 值时,会默认输出 null,但默认值可以改

Map<String,String> map = new TreeMap<>();  
map.put("及时雨","松江");  
map.put("齐天大圣","孙悟空");  
  
String val3 = map.getOrDefault("弼马温","没找到啊");  
System.out.println(val3);
/*
运行结果:
没找到啊
*/
  • 如果没有“弼马温”这个 Key,就取不到 Value,就给一个默认值“没找到啊

remove()

就是删除的意思,删除 Key 对应的映射关系

Map<String,String> map = new TreeMap<>();  
map.put("及时雨","松江");  
map.put("齐天大圣","孙悟空");  
String val3 = map.remove("齐天大圣");  
System.out.println(val3);
String val4 = map.get("齐天大圣");
System.out.println(val4);
/*
运行结果:
孙悟空
null
*/
  • 因为这个方法的返回值是 Value,所以还是会打印出“孙悟空”,但之后 Key(齐天大圣)和 Value(孙悟空)之间的映射关系就被删除了,不存在了
  • 所以第二次再 get 这个 KeyValue 值就找不到了

keySet()

将所有的 Key 都拿出来,放在一个 Set 集合中

Map<String,String> map = new TreeMap<>();  
map.put("及时雨","松江");  
map.put("齐天大圣","孙悟空");    
map.put("齐天大圣","弼马温");
  
Set<String> set = map.keySet();  
System.out.println(set);
System.out.println(map.get("齐天大圣"));
/*
运行结果:
[及时雨, 齐天大圣]
弼马温
*/
  • 因为 Key 都是 String,所以用一个 String 类型的 Set 进行接收
  • Key 是不能重复的,如果重复了,就会更新 Key 的值

entrySet()

如果想将 KeyValue 的映射关系一起返回,就可以调用 entrySet

Map<String,String> map = new TreeMap<>();  
map.put("及时雨","松江");  
map.put("齐天大圣","孙悟空");  
  
Set<Map.Entry<String,String>> entries = map.entrySet();  
System.out.println(entries);
System.out.println(===============);
for (Map.Entry<String,String> entry : entries){  
    System.out.println(entry);  
}
System.out.println(===============);
for (Map.Entry<String,String> entry : entries){  
    System.out.println("Key:"+entry.getKey()+" Value:"+entry.getValue());  
}
/*
运行结果:
[及时雨=松江, 齐天大圣=孙悟空]
===============
及时雨=松江
齐天大圣=孙悟空
===============
Key:及时雨 Value:松江
Key:齐天大圣 Value:孙悟空
*/
  • Entry 里面也可以单独的取出 Key 或者 Value
  • EntryMap接口的内置接口,其内部有
  • getKey 方法,用来获取 Key
  • getValue 方法,用来获取 Value
  • setValue 方法,用来更新 Value

注意事项

  1. Map 是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类 TreeMap 或者 HashMap (搜索树,红黑树)
  2. Map 中存放键值对的 Key 是唯一的,value 是可以重复的
  3. TreeMap 中插入键值对时,key 不能为空,否则就会抛 NullPointerException 异常,value 可以为空。但是 HashMapkeyvalue 都可以为空。
  4. Map 中的 Key 可以全部分离出来,存储到 Set 中来进行访问(因为 Key 不能重复)。
  5. Map 中的 value 可以全部分离出来,存储在 Collection 的任何一个子集合中(value 可能有重复)。
  6. Map 中键值对的 Key 不能直接修改,value 可以修改,如果要修改 key,只能先将该 key 删除掉,然后再来进行重新插入。
  7. TreeMap 中存储元素的时候,Key 一定是要可以比较的,因为 Key 的底层是红黑树,要将 Key 按大小顺序排列好。如果你传入一个类的时候,就要注意了
Map 底层结构 TreeMap HashMap
底层结构 红黑树 哈希桶
插入/删除/查找时间复杂度 O ( l o g N ) O(logN) O(logN) O ( 1 ) O(1) O(1)
是否有序 关于Key有序 无序
线程安全 不安全 不安全
插入/删除/查找区别 需要进行元素比较 通过哈希函数计算哈希地址
比较与覆写 key必须能够比较,否则会抛出

ClassCastException异常
自定义类型需要覆写equals和

hashCode方法
应用场景 需要Key有序场景下 Key是否有序不关心,需要更高的 时间性能


相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2577 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
163 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1576 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
975 14
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
220 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
734 9