从根到叶:深入了解Map和Set

窗间映出一片高远的天空,

向晚的天际宁静而又清明。

我孤独的心灵在幸福地哭泣,

它在为天空如此美好而高兴。

恬静的晚霞一片火红,

晚霞灼烧着我的热情。

此刻的世界没有别人,

只有上帝,我和天空。

                                                                                                            ——(俄)吉皮乌斯《瞬间》

一.概念及场景

Map和Set是两种常见的数据结构,用于在编程中组织和存储数据。它们通常在不同的场景中使用,具有不同的特点和用途。

1.Map(映射)是一种将键(key)与值(value)相关联的数据结构。它提供了一种通过键快速查找值的方式。在Map中,每个键是唯一的,而值可以重复。

Map的场景

  •  数据索引和快速查找:Map允许通过键快速查找对应的值,因此在需要高效的数据检索和索引的场景中经常使用。例如,将学生的学号与其成绩关联起来,可以通过学号快速查找对应的成绩。
  • 数据去重:由于Map中的键是唯一的,可以利用这个特性进行数据的去重操作。例如,可以使用Map来统计一段文本中不同单词的出现次数,只保留每个单词的一个实例。

2.Set(集合)是一种存储独特元素的数据结构,其中每个元素都是唯一的。Set通常用于判断元素是否存在,而不关心元素的顺序。Set的实现通常基于哈希表或树结构。

Set的场景

  •  数据去重:由于Set中的元素是唯一的,可以使用Set来去除重复的数据。例如,从一个数组中去除重复的元素,可以通过将数组元素添加到Set中来实现。
  • 成员关系判断:Set提供了高效的成员关系判断操作。例如,可以使用Set来判断一个元素是否属于某个特定集合。

相关模型

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

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

总结
Map适用于需要将键与值相关联的场景,提供了快速的查找和索引功能。Set适用于存储唯一元素的场景,并提供了高效的成员关系判断。两者都在去重操作中有应用,但在其他的具体应用场景中,选择使用Map还是Set取决于具体的需求和数据结构的特点。

二.Map的说明及使用

2.1关于Map说明

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

Map的特点和操作

  1. 键-值对:Map中的数据以键-值对的形式进行存储。每个键都与一个特定的值相关联。
  2. 唯一键:Map中的键是唯一的,不允许重复。当尝试添加一个已经存在的键时,新的值会覆盖旧的值。
  3. 快速查找:Map提供了快速的查找功能,可以通过键来获取对应的值。这使得Map在需要高效的数据检索和索引的场景中非常有用。
  4. 增加和删除元素:可以向Map中添加新的键-值对,也可以删除已有的键-值对。
  5. 迭代:Map可以进行迭代操作,以便对其中的键-值对进行遍历和处理。

Map的常用方法说明:

2.2HashMap和TreeMap

HashMap和TreeMap是两种常见的Map实现,它们在底层数据结构和性能特点上有所区别。

HashMap

  • 底层数据结构:HashMap使用哈希表(Hash Table)作为底层数据结构,通过哈希函数将键映射到数组索引位置。
  • 键的存储顺序:HashMap中的键是无序存储的,即键的顺序不受插入顺序的影响。
  • 时间复杂度:平均情况下,HashMap提供常数时间复杂度(O(1))的查找、插入和删除操作。
  • 适用场景:HashMap适用于需要快速查找、插入和删除键值对,并不关心顺序的场景。它在大多数情况下具有较高的性能。

HashMap的使用:

代码案例:

import java.util.HashMap;public class HashMapExample {public static void main(String[] args) {// 创建HashMap实例HashMap<String, Integer> hashMap = new HashMap<>();// 插入键值对hashMap.put("apple", 10);hashMap.put("banana", 5);hashMap.put("orange", 8);hashMap.put("grapes", 15);hashMap.put("kiwi", 20);hashMap.put("mango", 12);// 获取值int appleCount = hashMap.get("apple");System.out.println("Number of apples: " + appleCount);// 检查键是否存在boolean containsKey = hashMap.containsKey("banana");System.out.println("Contains banana: " + containsKey);// 删除键值对hashMap.remove("orange");// 迭代键值对for (String key : hashMap.keySet()) {int value = hashMap.get(key);System.out.println(key + ": " + value);}}
}

 运行如下:

TreeMap

  • 底层数据结构:TreeMap使用红黑树(Red-Black Tree)作为底层数据结构,保持键的有序性。
  • 键的存储顺序:TreeMap中的键是按照键的自然顺序或自定义的比较器顺序进行排序的。
  • 时间复杂度:TreeMap提供O(log n)的时间复杂度的查找、插入和删除操作,其中n是键值对的数量。
  • 适用场景:TreeMap适用于需要按照键的顺序进行遍历和检索的场景。它可以用于范围查询,例如,查找最小键、最大键以及在两个键之间的键值对。

 TreeMap的使用:

import java.util.TreeMap;public class TreeMapExample {public static void main(String[] args) {// 创建TreeMap实例TreeMap<String, Integer> treeMap = new TreeMap<>();// 插入键值对treeMap.put("apple", 10);treeMap.put("banana", 5);treeMap.put("orange", 8);treeMap.put("grapes", 15);treeMap.put("kiwi", 20);treeMap.put("mango", 12);// 获取值int appleCount = treeMap.get("apple");System.out.println("Number of apples: " + appleCount);// 检查键是否存在boolean containsKey = treeMap.containsKey("banana");System.out.println("Contains banana: " + containsKey);// 删除键值对treeMap.remove("orange");// 迭代键值对for (String key : treeMap.keySet()) {int value = treeMap.get(key);System.out.println(key + ": " + value);}}
}

运行如下:

 HashMap和TreeMap的区别:

底层数据结构:

  • HashMap使用哈希表(数组+链表/红黑树)实现,通过哈希函数将键映射到数组索引位置,解决哈希冲突使用链表或红黑树。
  • TreeMap使用红黑树实现,保持键的有序性,每个节点都遵循二叉搜索树的性质。

插入和查找操作性能:

  • HashMap的插入和查找操作的平均时间复杂度为O(1),即常数时间复杂度。但在发生哈希冲突时,性能可能会下降,需要通过链表或红黑树进行顺序查找,最坏情况下的时间复杂度为O(n)。
  • TreeMap的插入和查找操作的时间复杂度为O(log n),其中n是元素的数量。由于使用红黑树作为底层数据结构,保持有序性,因此查找操作更加高效。

排序特性:

  • HashMap不保持键的有序性,键的顺序是不确定的。
  • TreeMap根据键的自然顺序或自定义比较器对键进行排序,提供有序的键值对遍历。

存储空间:

  • HashMap在内部使用数组来存储键值对,不保证顺序,因此通常占用较少的存储空间。
  • TreeMap使用红黑树作为底层数据结构,保持键的有序性,因而在存储大量数据时占用的存储空间通常会更多。

参考下图: 

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

Map.Entry<K, V> Map 内部实现的用来存放 <key, value> 键值对映射关系的内部类 ,该内部类中主要提供了<key, value>的获取, value 的设置以及 Key 的比较方式。
提供方法:

代码案例:

import java.util.HashMap;
import java.util.Map;public class MapExample {public static void main(String[] args) {// 创建一个HashMap实例Map<String, Integer> map = new HashMap<>();// 添加键值对到Map中map.put("apple", 10);map.put("banana", 5);map.put("orange", 8);// 遍历Map中的条目for (Map.Entry<String, Integer> entry : map.entrySet()) {String key = entry.getKey();Integer value = entry.getValue();System.out.println("Key: " + key + ", Value: " + value);}// 获取指定键的值int appleCount = map.get("apple");System.out.println("Number of apples: " + appleCount);// 使用setValue()方法更新值int newBananaCount = 7;map.entrySet().stream().filter(entry -> entry.getKey().equals("banana")).findFirst().ifPresent(entry -> entry.setValue(newBananaCount));// 输出更新后的值int updatedBananaCount = map.get("banana");System.out.println("Updated number of bananas: " + updatedBananaCount);}
}

 运行如下:

注意 Map.Entry<K,V> 并没有提供设置 Key 的方法

 三.Set的说明及使用

 3.1关于Set说明

SetMap主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key

Set的特点和操作:

  1. 唯一性:Set中的元素是唯一的,不会出现重复的元素。如果尝试将重复的元素添加到Set中,它将被忽略。

  2. 无序性:Set中的元素没有特定的顺序。这意味着你不能通过索引来访问Set中的元素。如果需要按特定顺序遍历元素,可以将Set转换为列表或使用其他有序数据结构。

  3. 可变性:Set是可变的,可以添加或删除元素。可以通过添加新元素或删除现有元素来修改Set。

  4. 高效性:Set提供了高效的成员检查操作。由于Set使用了哈希表或类似的数据结构来实现,它可以在平均情况下以常量时间复杂度(O(1))执行插入、删除和查找操作。

  5. 迭代性:Set支持迭代操作,可以使用循环遍历Set中的所有元素。

  6. 数学集合操作:Set还支持常见的数学集合操作,例如并集、交集和差集。这些操作使得可以对Set进行合并、比较和筛选等操作。

Set常用方法说明
注意:
  •  Set是继承自Collection的一个接口类
  •  Set中只存储了key,并且要求key一定要唯一
  •  TreeSet的底层是使用Map来实现的,其使用keyObject的一个默认对象作为键值对插入到Map中
  • Set最大的功能就是对集合中的元素进行去重
  • 实现Set接口的常用类有TreeSetHashSet,还有一个LinkedHashSetLinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
  • Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
  • TreeSet中不能插入nullkeyHashSet可以

 3.2TreeSet和HashSet

HashSet

  • 唯一性:HashSet中的元素是唯一的,不会存在重复元素。如果尝试将重复的元素添加到HashSet中,它将被忽略。

  • 无序性:HashSet中的元素没有特定的顺序。元素在HashSet中的存储位置是根据元素的哈希码计算得出的,并不与插入顺序或值的大小相关。

  • 元素存储:HashSet使用哈希表(Hash Table)来存储元素。哈希表通过哈希函数将元素的值映射到桶(bucket)中。每个桶可以包含一个或多个元素。通过哈希函数和桶的结构,HashSet实现了高效的插入、删除和查找操作。

  • 性能:HashSet的插入、删除和查找操作的平均时间复杂度是常数时间复杂度(O(1)),在大多数情况下具有很高的性能。但是,在某些情况下,由于哈希冲突(多个元素映射到同一个桶),性能可能会下降,导致操作的时间复杂度变为O(n)。

  • 迭代性:HashSet支持迭代操作,可以使用增强的for循环或迭代器来遍历HashSet中的所有元素。但是,由于HashSet是无序的,迭代顺序不可预测。

  • 对象比较:为了正确地判断元素的相等性,HashSet要求元素类正确实现equals()hashCode()方法。equals()方法用于比较两个元素的内容是否相等,而hashCode()方法用于计算元素的哈希码,以确定元素在哈希表中的存储位置。

import java.util.HashSet;
import java.util.Set;public class HashSetExample {public static void main(String[] args) {// 创建一个HashSet实例Set<String> set = new HashSet<>();// 添加元素到HashSetset.add("apple");set.add("banana");set.add("orange");// 输出HashSet的大小System.out.println("HashSet size: " + set.size());// 检查元素是否存在boolean containsOrange = set.contains("orange");System.out.println("Set contains 'orange': " + containsOrange);// 移除元素set.remove("banana");// 遍历HashSet中的元素System.out.println("HashSet elements:");for (String element : set) {System.out.println(element);}// 清空HashSetset.clear();// 检查HashSet是否为空boolean isEmpty = set.isEmpty();System.out.println("HashSet is empty: " + isEmpty);}
}

运行如下:

TreeSet:

  • 唯一性:TreeSet中的元素是唯一的,不会存在重复元素。如果尝试将重复的元素添加到TreeSet中,它将被忽略。

  • 排序性:TreeSet中的元素是有序的,根据元素的自然排序或指定的比较器排序。默认情况下,元素被按升序排序。

  • 元素存储:TreeSet使用红黑树数据结构进行存储。红黑树是一种自平衡的二叉搜索树,它通过保持树的平衡性,提供了高效的插入、删除和查找操作。元素在红黑树中根据其排序顺序进行存储。

  • 性能:TreeSet的插入、删除和查找操作的平均时间复杂度是O(log n),其中n是TreeSet中的元素数量。由于红黑树的平衡性,这些操作的性能相对稳定,不会受到元素的插入顺序的影响。

  • 迭代性:TreeSet支持迭代操作,可以使用增强的for循环或迭代器来遍历TreeSet中的所有元素。由于TreeSet是有序的,迭代顺序将按照元素的排序顺序进行。

  • 对象比较:为了正确地判断元素的相等性和排序顺序,TreeSet要求元素类实现Comparable接口或提供自定义的比较器。Comparable接口的compareTo()方法用于比较两个元素的顺序。

import java.util.TreeSet;
import java.util.Set;public class TreeSetExample {public static void main(String[] args) {// 创建一个TreeSet实例Set<String> set = new TreeSet<>();// 添加元素到TreeSetset.add("apple");set.add("banana");set.add("orange");// 输出TreeSet的大小System.out.println("TreeSet size: " + set.size());// 检查元素是否存在boolean containsOrange = set.contains("orange");System.out.println("Set contains 'orange': " + containsOrange);// 移除元素set.remove("banana");// 遍历TreeSet中的元素System.out.println("TreeSet elements:");for (String element : set) {System.out.println(element);}// 获取最小元素String firstElement = ((TreeSet<String>) set).first();System.out.println("First element: " + firstElement);// 获取最大元素String lastElement = ((TreeSet<String>) set).last();System.out.println("Last element: " + lastElement);}
}

 TreeSet和HashSet的区别:

结语:Map和Set是Java集合框架中常用的数据结构。Map是一种键值对的数据结构,用于存储和操作具有唯一键和对应值的元素,适用于缓存、数据索引和快速查找等场景。Set是一种无序、不重复元素的集合,用于存储和操作独立的元素,适用于去重和判断元素是否存在的场景。它们提供了高效的操作和查找能力,并有多个实现类可供选择,如HashMap、TreeMap、HashSet和TreeSet等,根据具体需求选择合适的实现类。

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

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

相关文章

SpringBlade error/list SQL 注入漏洞复现

0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade 框架后台 /api/blade-log/error/list路径存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数…

让生活更加精致的APP?

晚上好&#xff0c;今天博主来介绍几款帮助你条理生活的APP&#xff0c;让你的生活更加精致&#xff0c;充满仪式感。 一&#xff0e;格志日记 一款以“格子”的方式记录日记的APP&#xff0c;非常简单明了&#xff0c;用户可以依据自己的喜好&#xff0c;来自由定义或者删除格…

SpringBoot实战项目——博客笔记项目

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、项目介绍二、项目的整体框架 2.1 数据库模块 2.2 前端模块 2.3 后端模块三、项目图片展示四、项目的实现 4.1 准备工作 4.…

【R语言实战】——金融时序分布拟合

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

Android audiotrack尾帧无声

前言 产品一直有用户反馈音频截断问题。在机遇巧合下现学现卖音频知识处理相关问题。 问题描述 我们查看以下简化播放器代码&#xff1a; class AACPlayer(private val filePath: String) {private val TAG "AACPlayer"private var extractor: MediaExtractor? …

TortoiseSVN 报错:The server unexpectedly closed the connetion

前言 CentOS7Linux 安装subversionmod_dav_svn&#xff0c;搭建subversion(svn)服务器 The server unexpectedly closed the connetion 解决办法 重启Apache服务 shell> systemctl restart httpd

uniapp—day02

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 WXML 和HTML区…

系统及其分类

系统定义 系统&#xff1a;指若干相互关联的事物组合而成的具有特定功能的整体。 系统的基本作用&#xff1a;对输入信号进行加工和处理&#xff0c;将其转换为所需要的输出信号。 系统分类 系统的分类错综复杂&#xff0c;主要考虑其数学模型的差异来划分不同类型。主要分为…

使用reprepro+nginx搭建apt服务器

目录 项目背景 项目要求 项目开发过程 1、apt服务器的搭建 2、实现自定义指定源文件列表来实现apt update更新 3、实现软件启动时自动更新 4. source.list中镜像源地址的格式 项目开发的难点/坑点 总结 项目背景 前面写过一篇“利用Nginx搭建一个apt服务器”&#xff…

Midjourney绘图欣赏系列(十)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

vue项目:webpack打包优化实践

本文目录 一、项目基本信息二、分析当前项目情况1、使用 webpack-bundle-analyzer 插件2、使用 speed-measure-webpack-plugin 插件 三、解决构建问题1、caniuse-lite 提示的问题2、 warning 问题 四、打包速度优化1、修改source map2、处理 loader 五、webpack性能优化1、使用…

idea+maven+tomcat+spring 创建一个jsp项目

概述&#xff1a;我真服了&#xff0c;这个垃圾学校还在教jsp&#xff0c;这种技术我虽然早会了&#xff0c;但是之前搞的大多都是springboot web类型的&#xff0c;这里我就复习一下&#xff0c;避免以后忘记这种垃圾技术 第一步&#xff1a;创建maven项目 第二步&#xff1a…

HUAWEI 华为交换机 配置 MAC 地址漂移检测示例

组网需求 如 图 2-17 所示&#xff0c;网络中两台 LSW 间网线误接形成了网络环路&#xff0c;引起 MAC 地址发生漂 移、MAC 地址表震荡。 为了能够及时检测网络中出现的环路&#xff0c;可以在 Switch 上配置 MAC 地址漂移检测功能&#xff0c; 通过检测是否发生MAC 地址漂移…

从零搭建Vue项目

目录 环境准备 NodeJS安装 ​编辑 2. 选择安装目录 3. 验证NodeJS环境变量 4. 配置npm的全局安装路径 5. 切换npm的淘宝镜像 6. 安装Vue-cli Vue项目创建 1. 打开UI界面 2. 打开项目管理器 3. 创建项目 vue项目目录结构介绍 运行vue项目 Vue项目开发流程 Vue组…

十五、计算机视觉-sobel算子

文章目录 前言一、sobel算子的概念二、sobel算子的计算方式三、具体实现 前言 上节课我们学习了梯度的知识&#xff0c;学习了如何去计算梯度&#xff0c;本节我们继续学习计算梯度的方法&#xff0c;本节我们学习使用Sobel算子计算梯度&#xff0c;这与上节课梯度计算方法有所…

jmeter发送请求参数如何使用变量

问题描述 发送jmeter请求时&#xff0c;想设置请求参数为变量 解决方法

190基于matlab的tfrSTFT时频分布图

基于matlab的tfrSTFT时频分布图&#xff0c;计算时间序列的STFT时频分布图&#xff0c;得到瞬时频率。通过GUI可以调节图像的展示样式。程序已调通&#xff0c;可直接运行。 190 STFT时频分布图 瞬时频率 能量谱 (xiaohongshu.com)

excel统计分析——一元直线回归

参考资料&#xff1a;生物统计学 两个具有因果关系的协变量如果呈直线关系&#xff0c;可以用直线回归模型来分析两个变量的关系。直线回归&#xff08;linear regression&#xff09;是回归分析中最简单的类型&#xff0c;建立直线回归方程并经检验证明两个变量存在直线回归关…

如何使用 templ 在 Go 中编写 HTML 用户界面?

简介 templ 是一个在 Go 中编写 HTML 用户界面的语言。使用 templ&#xff0c;我们可以创建可呈现 HTML 片段的组件&#xff0c;并将它们组合起来创建屏幕、页面、文档或应用程序。 安装 我们可以通过以下两种方式来安装 templ&#xff1a; go 安装 首先&#xff0c;我们需…

软件需求分析报告-word

第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 5.6 其他信息安全措施 第6章 其他非功能需求 6.1 性能设计 6.2 稳定性设计 6.3 安全性设计 6.4 兼容性设计…