Java-集合(5)
Map接口
JDK8
Map接口实现子类的特点
- Map和Collection是并列关系,Map用于保存具有映射关系的数据:Key-Value
- Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
- Map中的key不允许重复,原因和HashSet一样
- Map中的value可以重复
- Map的key可以为null,value也可以为null,但是key只能有一个null,value可以有多个null只要key不同就行
- 常用String类为Map的key
- key和value之间存在单向一对一关系,即通过key找到对应的value。可以理解为key相当于身份证号,value是对应的人,人可以重复名字样貌等,但是身份证不能重复。
- 当加入一个重复的key和不重复的value时,相当于替换
测试:
public class test1 {public static void main(String[] args) {Map map = new HashMap();map.put("nbo1","张三");map.put("nbo2","李四");map.put("nbo3","王五");map.put("nbo1","李向");System.out.println(map);}
}
运行结果:
{nbo2=李四, nbo1=李向, nbo3=王五}
在之前Collection接口实现集合类,都是使用key来直接保存存储的数据。而Map接口实现集合类会使用key和value两个相互映射来保存数据,key可以看作是一个序号或者身份证号,value才是真正保存的数据
理解:Map存放的key-value是放在一个Node中的,又因为Node实现了Entry接口,所以也说一对k-v也是一个Entry**

我们知道当使用Map实现集合类存放了一个元素时,会有key和value,也就是键和值,键key可以看作是一个序号,值valuie可以看作是内容,一个序号对应一个内容,而这两个东西是存放在一个Node节点中的。但是因为Map不是Collection接口,Map没有实现iterator接口,所以要遍历不是很方便。因此在添加元素时除了会保存到table数组时,还会做一件事情就是保存到一个EntrySet集合中,EntrySet集合中的保存类型不是Node类型而是Entry类型。
但是这里的意思不是说把table中的数组都复制一份到EntrySet集合中,而是单纯的引用,也就是把EntrySet中的一个个Entry指向的还是table中的一个个Node。而为什么要做这么一件事呢,这是因为在EntrySet集合中保存的key是Set接口类型的value是Collection接口类型的,当然实际运行类型还是Node,只不过这样就可以使用迭代器了。
public class test1 {public static void main(String[] args) {Map map = new HashMap();map.put("nbo1","张三");map.put("nbo2","李四");map.put("nbo3","王五");map.put("nbo1","李向");Set set = map.entrySet();for (Object obj:set) {Map.Entry entry = (Map.Entry) obj;System.out.println(entry.getClass());System.out.println(entry.getKey()+"-"+entry.getValue());}}
}
运行结果:
class java.util.HashMapNodenbo2−李四classjava.util.HashMapNode nbo2-李四 class java.util.HashMapNodenbo2−李四classjava.util.HashMapNode
nbo1-李向
class java.util.HashMap$Node
nbo3-王五
Map接口实现类的常用方法
口语说法:key:键 ———— value:值
- put(key,value);添加,当再次添加同一个键,但是值不同时,会对值进行替换
- remove(key);根据键删除这对键和值
- get(key);根据键获取值
- size();获取当前集合的元素个数
- isEmpty():判断当前集合元素个数是否为0
- containsKey(key);查找传入的键是否存在
- clear:清除集合所有元素,归0
使用演示
public class test2 {public static void main(String[] args) {Map map = new HashMap();// 1. put(key,value);添加,当再次添加同一个键,但是值不同时,会对值进行替换map.put("no1","李青");map.put("no2","绿意");map.put("no1","李青");System.out.println(map);
// 2. remove(key);根据键删除这对键和值map.remove("no1");System.out.println(map);
// 3. get(key);根据键获取值System.out.println(map.get("no2"));
// 4. size();获取当前集合的元素个数System.out.println(map.size());
// 5. isEmpty():判断当前集合元素个数是否为0System.out.println(map.isEmpty());
// 6. containsKey(key);查找传入的键是否存在System.out.println(map.containsKey("no2"));
// 7. clear:清除集合所有元素,归0map.clear();System.out.println(map);}
}
运行结果:
{no2=绿意, no1=李青}
{no2=绿意}
绿意
1
false
true
{}
Map接口实现类的六大遍历方式
上面了解到了map存入的数据还会有一个EntrySet集合指向table数组中的数据,所以遍历也是围绕这个来操作
Map实现接口可以分为三大类:每类有两种方式
1.获取键key,再通过键来获取值value
2.直接获取值value,但是无法通过值value获取key,所以只能输出value
3.通过EntrySet,同时获取到键和值
遍历用到的方法
- KeySet:获取所有键
- entrySet:获取所有键和值k-v
- values:获取所有值
演示:
public class test3 {public static void main(String[] args) {Map map = new HashMap();map.put("no1","淘宝");map.put("no2","天猫");map.put("no3","京东");//第一类:获取所有键,再通过get方法获取值。//第一种方式:获取键后使用增强forSystem.out.println("第一种");Set set = map.keySet();for (Object key:set) {System.out.println(key+"-"+map.get(key));}System.out.println("第二种");//第二种方式:获取键后,使用迭代器Iterator iterator = set.iterator();while (iterator.hasNext()) {Object next = iterator.next();System.out.println(next+"-"+map.get(next));}//第二类:获取所有值//第三种方式:增强for,直接输出valueSystem.out.println("第三种");Collection value = map.values();for (Object o: value) {System.out.println(o);}//第四种:使用迭代器直接输出System.out.println("第四种");Iterator iterator2 = value.iterator();while (iterator2.hasNext()) {Object next = iterator2.next();System.out.println(next);}//第三类:获取所有键和值,再向下转型成Entry,使用它的getKey和getValue方法//第五种:获取所有键和值,增强for操作System.out.println("第五种");Set entrySet = map.entrySet();for (Object e:entrySet) {Map.Entry entry = (Map.Entry) e;System.out.println(entry.getKey()+"-"+entry.getValue());}//第六种:迭代器操作System.out.println("第六种");Iterator iterator1 = entrySet.iterator();while (iterator1.hasNext()) {Object next = iterator1.next();Map.Entry entry = (Map.Entry) next;System.out.println(entry.getKey()+"-"+entry.getValue());}}
}
运行结果:
第一种
no2-天猫
no1-淘宝
no3-京东
第二种
no2-天猫
no1-淘宝
no3-京东
第三种
天猫
淘宝
京东
第四种
天猫
淘宝
京东
第五种
no2-天猫
no1-淘宝
no3-京东
第六种
no2-天猫
no1-淘宝
no3-京东
Map小练习
使用HashMap添加三个员工对象,要求:
键:员工id
值:员工对象
且遍历显示工资18000的员工至少使用两种遍历方式
员工类:姓名,工资,员工id
public class test4 {@SuppressWarnings({"all"})public static void main(String[] args) {HashMap map = new HashMap();staff s1 = new staff(01,"李四",16000);staff s2 = new staff(02,"王五",23000);staff s3 = new staff(03,"赵三",12000);staff s4 = new staff(04,"李明",19000);map.put(s1.id,s1);map.put(s2.id,s2);map.put(s3.id,s3);map.put(s4.id,s4);//第一种:获取直接获取所有值,判断运行类型是否是staff,如果是就向下转型,再判断薪水决定是否输出Collection c = map.values();for (Object value:c) {if (value instanceof staff){staff s = (staff) value;if (s.sal>18000){System.out.println(s);}}}//第二种:直接获取所有键和值Set entrySet = map.entrySet();for (Object entry:entrySet) {Map.Entry entry1 = (Map.Entry) entry;staff s = (staff) entry1.getValue();if (s.sal>18000){System.out.println(s);}}}
}
class staff{String name;int id;double sal;public staff(int id,String name,double sal) {this.name = name;this.id = id;this.sal = sal;}@Overridepublic String toString() {return "staff{" +"name='" + name + '\'' +", id=" + id +", sal=" + sal +'}';}
}
HashMap小结
- Map接口的常用实现类:HashMap,Hashtable,Properties,ThreeMap
- HashMap是Map接口使用频率最高的实现类
- HashMap是以key-value对的方式来存储数据的
- key不能重复,但是值可以重复,运行使用null作为存入的数据
- 如果添加相同的key,则会覆盖原来的key-value,等同于替换
- 与HashSet一样,HashMap不保证映射的顺序,因为底层是以hash表的方式来存储的(jdk8的hashMap底层:数组+链表+红黑树)
- HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized
HashMap底层机制及源码刨析
扩容机制
- HashMap底层维护了Node类型的数组table,默认为null
- 当创建对象时,将加载因子(loadfactor)初始化为0.75.也就是当table数组存放的元素数到达整体数组大小的75%时,就会进行扩容
- 当添加k-y时,会先通过key的哈希值得到在table的索引,然后判断该索引是否有元素,如果没有则直接添加,如果有元素就判断该位置的元素key和准备添加的key是否相等,如果相等则直接替换value,如果不相等则判断是树结构还是链表结构,如果是链表结构就直接与下一个元素判断。
- 第一次添加,需要扩容table数组容量为16,扩容临界值(threshold)为12,(16*0.75)
- 非第一次扩容就是扩容table容量为原来的2倍,临界值也为原来的2倍,以此类推
- 在java8中,如果一条链表的元素超过了8个且table的大小>=64就会进行树化,如果链表元素超过8个,但是table数组的大小还未超过64,那么就会先进行数组扩容,直到数组大小到达64才会进行树化
Hashtable

Hashtable也是Map接口的实现类,与HashMap是同级关系
Hashtable基本介绍
- 存放的元素也是键和值:key-value
- Hashtable的k-v都不能存放null,负责会抛出异常
- Hashtable的使用方法基本上和HashMap一致
- Hashtable是线程安全的,HashMap是线程不安全的
Hashtable底层介绍
初始
- 底层由数组Hashtable$Entry[]初始化大小为11
- 初始临界值threeshold 8 = 11*0.75,所以也是到75%就扩容
- Hashtable除了第一次初始化大小,后面扩容机制为 *2+1.
Hashtable和HashMap的选择
| 实现类 | 出现版本 | 线程安全 | 效率 | 是否可以存null |
|---|---|---|---|---|
| HashMap | 1.2 | 不安全 | 高 | 允许 |
| Hashtable | 1.0 | 安全 | 较低 | 不允许 |
Properties
Properties基本介绍
- Properties类继承于Hahstable类,同样实现了Map接口,也是一种键key-值value的形式保存数据
- Properties的使用特点和Hashtable类似
- Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象进行读取和修改(在IO流说明)
Properties的增删改查
public class test5 {public static void main(String[] args) {Properties properties = new Properties();//增加properties.put("no1",100);properties.put("no2",200);//删除,根据key,删除key-valueproperties.remove("no1");System.out.println(properties);//改(替换)properties.put("no2",90);System.out.println(properties);//查,根据key获取valueSystem.out.println(properties.get("no2"));}
}
相关文章:
Java-集合(5)
Map接口 JDK8 Map接口实现子类的特点 Map和Collection是并列关系,Map用于保存具有映射关系的数据:Key-ValueMap中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中Map中的key不允许重复,原因和HashSet一样Map…...
研制过程评审活动(四)设计定型阶段
1、设计定型阶段主要任务 设计定型的主要任务是对武器装备性能和使用要求进行全面考核,以确认产品是否达到《研制任务书》和《研制合同》的要求。 设计定型阶段应最终确定《产品规范》、《工艺规范》和《材料规范》的正式版本,并形成正式的全套生产图样、有关技术文件及目…...
【Linux】进程替换
文章目录进程程序替换替换原理替换函数函数返回值函数命名理解在makefile文件中一次生成两个可执行文件总结:程序替换时运行其它语言程序进程程序替换 程序要运行要先加载到内存当中 , 如何做到? 加载器加载进来,然后程序替换 为什么? ->冯诺依曼 因为CPU读取数据的时候只…...
LeetCode171-Excel表列序号(进制转换问题)
LeetCode171-Excel表列序号1、问题描述2、解题思路:进制转换3、代码实现1、问题描述 给你一个字符串columnTitle,表示Excel表格中得列名称。返回该列名称对应得列序号。 例如: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 …...
React SSR
ReactDOMServer 参考链接:https://zh-hans.reactjs.org/docs/react-dom-server.html ReactDOMServer 对象允许你将组件渲染成静态标记。通常,它被使用在 Node 服务端上 // ES modules import * as ReactDOMServer from react-dom/server; // CommonJS v…...
如何系统地优化页面性能
页面优化,其实就是要让页面更快地显示和响应。由于一个页面在它不同的阶段,所侧重的关注点是不一样的,所以如果要讨论页面优化,就要分析一个页面生存周期的不同阶段。 通常一个页面有三个阶段:加载阶段、交互阶段和关…...
Vulnhub 渗透练习(八)—— THE ETHER: EVILSCIENCE
环境搭建 环境下载 靶机和攻击机网络适配都选 NAT 即可。 信息收集 主机扫描 两个端口,22 和 80,且 apache httpd 2.4.0~2.4.29 存在换行解析漏洞。 Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中…...
华为OD机试题 - 水仙花数 2(JavaScript)| 代码+思路+重要知识点
最近更新的博客 华为OD机试题 - 字符串加密(JavaScript) 华为OD机试题 - 字母消消乐(JavaScript) 华为OD机试题 - 字母计数(JavaScript) 华为OD机试题 - 整数分解(JavaScript) 华为OD机试题 - 单词反转(JavaScript) 使用说明 参加华为od机试,一定要注意不要完全背…...
字符设备驱动基础(二)
目录 一、五种IO模型------读写外设数据的方式 二、阻塞与非阻塞 三、多路复用 3.1 应用层:三套接口select、poll、epoll 3.2 驱动层:实现poll函数 四、信号驱动 4.1 应用层:信号注册fcntl 4.2 驱动层:实现fasync函数 一、…...
看见统计——第三章 概率分布
看见统计——第三章 概率分布 参考 https://github.com/seeingtheory/Seeing-Theory中心极限定理 概率分布描述了随机变量取值的规律。 随机变量Random Variables 🔥 定义:将样本空间中的结果映射到实数的函数 XXX 称为随机变量(random variable)&a…...
【基于众包标注的语文教材句子难易度评估研究 论文精读】
基于众包标注的语文教材句子难易度评估研究 论文精读信息摘 要0 引言1 相关研究2 众包标注方法3 语料库构建3.1 数据收集3.1 基于五点量表的专家标注3.3 基于成对比较的众包标注4 特征及模型4.1 特征抽取4.2 模型与实验设计4.2.1 任务一:单句绝对难度评估4.2.2 任务二:句对相对…...
实例五:MATLAB APP design-APP登录界面的设计
一、APP 界面设计展示 注:在账号和密码提示框输入相应的账号和密码后,点击登录按钮,即可跳转到程序中设计的工作界面。 二、APP设计界面运行结果展示...
作用域和闭包:
1、LHS和RHS查询编译一段代码,需要js引擎和编译器(js引擎负责整个程序运行时所需的各种资源的调度,编译器只是js引擎的一部分,负责将JavaScript源码编译成机器能识别的机器指令,然后交给引擎运行)编译的过程…...
Vue常见面试题?
1、说说你对SPA单页面的理解,它的优缺点是什么? SPA(single-page application)仅在Web页面初始化时加载相应的HTML、JavaScript和CSS。一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机…...
前端借助Canvas实现压缩图片两种方法
一、具体代码 1、利用canvas压缩图片方法一 // 第一种压缩图片方法(图片base64,图片类型,压缩比例,回调函数)// 图片类型是指 image/png、image/jpeg、image/webp(仅Chrome支持)// 该方法对以上三种图片类型都适用 压缩结果的图片base64与原类型相同// …...
2023年美赛C题Wordle预测问题二建模及Python代码详细讲解
更新时间:2023-2-19 相关链接 (1)2023年美赛C题Wordle预测问题一建模及Python代码详细讲解 (2)2023年美赛C题Wordle预测问题二建模及Python代码详细讲解 (3)2023年美赛C题Wordle预测问题三、四…...
【算法】双指针
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下来🐾 文章目录1.双指针分类2.双指针思想3.双指针应用1.双指针分类 常见问题分类 (1) 对于一个序列,用两个指针维护一段区间, 比如快速排序。 …...
Flutter-Widget-学习笔记
Widget 是整个视图描述的基础。 参考:https://docs.flutter.dev/resources/architectural-overview Widget 到底是什么呢? Widget 是 Flutter 功能的抽象描述,是视图的配置信息,同样也是数据的映射,是 Flutter 开发框…...
easyExcel 写复杂表头
写模板 模板图片: 实体类(这里没有用Data 是因为Lombok和easyExcal的版本冲突,在导入读取的时候获取不到值) package cn.iocoder.yudao.module.project.controller.admin.goods.vo;import com.alibaba.excel.annotation.ExcelI…...
关于线程池的执行流程和拒绝策略
使用线程池的好处为: 降低资源消耗:减少线程的创建和销毁带来的性能开销。 提高响应速度:当任务来时可以直接使用,不用等待线程创建 可管理性: 进行统一的分配,监控,避免大量的线程间因互相抢…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
