Java 中 ConcurrentHashMap 和 HashMap 能存 null 吗?深挖原理和使用场景
前言
当你使用 HashMap
或 ConcurrentHashMap
时,可能会冒出一个经典问题:它们能存储 null
键或 null
值吗? 初学者可能觉得无所谓,试一下不就知道了,但在真实项目中,这个问题可能导致严重的 bug。今天我们就来系统讲解这两个常用集合类对 null
键和值的支持情况,并深入分析其设计背后的逻辑。
一、结论先行
集合类型 | 是否允许 null 键 | 是否允许 null 值 |
---|---|---|
HashMap | 允许 | 允许 |
ConcurrentHashMap | 不允许 | 不允许 |
简单来说:
HashMap
:对null
键和null
值都很包容。ConcurrentHashMap
:对null
直接说“不”。
接下来我们看看这些行为的原因和实现细节。
二、HashMap
的行为分析
1. 支持 null
键和 null
值
HashMap
是 Java 中最常用的非线程安全集合,它允许存储一个 null
键和多个 null
值。
示例:
import java.util.HashMap;public class HashMapNullExample {public static void main(String[] args) {HashMap<String, String> map = new HashMap<>();map.put(null, "这是一个 null 键");map.put("key1", null);map.put("key2", null);System.out.println("HashMap: " + map);}
}
输出:
HashMap: {null=这是一个 null 键, key1=null, key2=null}
2. 为什么允许 null
?
-
null
键:-
在
HashMap
的实现中,null
键被特殊处理。如果键是null
,则会直接存储到table
的第一个桶(table[0]
)中,而不需要计算哈希值。 -
源码片段(Java 8
put
方法):
if (key == null)return putForNullKey(value);
-
-
null
值:HashMap
没有对值进行特殊约束,只要键有效,值就可以为null
。
三、ConcurrentHashMap
的行为分析
1. 不支持 null
键和 null
值
ConcurrentHashMap
是线程安全的 Map,它对 null
键和值都不友好,如果尝试存储 null
,会直接抛出 NullPointerException
。
示例:
import java.util.concurrent.ConcurrentHashMap;public class ConcurrentHashMapNullExample {public static void main(String[] args) {ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();// 测试 null 键try {map.put(null, "null 键");} catch (NullPointerException e) {System.out.println("不支持 null 键: " + e);}// 测试 null 值try {map.put("key1", null);} catch (NullPointerException e) {System.out.println("不支持 null 值: " + e);}}
}
输出:
不支持 null 键: java.lang.NullPointerException
不支持 null 值: java.lang.NullPointerException
2. 为什么不允许 null
?
-
线程安全性考虑:
ConcurrentHashMap
是为高并发设计的,
null
键或值可能会导致难以调试的空指针问题。例如:
- 如果
get(key)
返回null
,你无法确定是因为键不存在,还是值本身就是null
。 - 在多线程场景中,
null
键或值的存在可能会导致更复杂的边界条件和线程安全问题。 ConcurrentHashMap
的设计原则是:尽量避免模棱两可的行为,让开发者在代码中明确处理空值逻辑。
- 如果
四、背后的设计哲学
1. HashMap
的包容性
HashMap
是单线程的,设计上更加灵活,主要用于非并发场景。允许 null
键和值,符合它“工具箱”式的轻量设计。
2. ConcurrentHashMap
的严格性
ConcurrentHashMap
强调高效和安全,它的限制(不允许 null
)是为了防止并发场景中的潜在问题,并帮助开发者写出更清晰的代码。
五、常见误区
误区 1:ConcurrentHashMap
支持 null
键和值
很多初学者以为所有的 Map
实现都支持 null
键和值,实际并非如此。记住:ConcurrentHashMap
对 null
说“不”!
误区 2:HashMap
中多个 null
键是可以的
HashMap
中最多只能有一个 null
键,多个 null
键会导致覆盖。
示例:
HashMap<String, String> map = new HashMap<>();
map.put(null, "值1");
map.put(null, "值2");
System.out.println(map); // 输出: {null=值2}
六、如何优雅处理 null
?
1. 使用 Optional
替代 null
值
在需要明确区分值是否为空时,可以使用 Optional
来代替 null
:
import java.util.Optional;HashMap<String, Optional<String>> map = new HashMap<>();
map.put("key1", Optional.ofNullable(null));
System.out.println(map.get("key1").orElse("默认值"));
2. 初始化 Map 时确保没有 null
键和值
对于不允许存储 null
的 Map(如 ConcurrentHashMap
),需要手动检查输入:
if (key == null || value == null) {throw new IllegalArgumentException("键和值均不能为空");
}
七、总结
特性 | HashMap | ConcurrentHashMap |
---|---|---|
允许 null 键 | 是 | 否 |
允许 null 值 | 是 | 否 |
线程安全性 | 否 | 是 |
典型使用场景 | 单线程、灵活性需求高 | 多线程、高并发环境 |
记住这些差异,你就能在项目中更高效地选择合适的 Map 类型。如果你有任何疑问,欢迎留言一起探讨! 😊
相关文章:
Java 中 ConcurrentHashMap 和 HashMap 能存 null 吗?深挖原理和使用场景
前言 当你使用 HashMap 或 ConcurrentHashMap 时,可能会冒出一个经典问题:它们能存储 null 键或 null 值吗? 初学者可能觉得无所谓,试一下不就知道了,但在真实项目中,这个问题可能导致严重的 bug。今天我们…...
【JavaWeb后端学习笔记】Spring Task实现定时任务处理
Spring Task是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。 主要的应用场景有:纪念日提醒,处理订单未支付,还款提醒等。 1、corn表达式 使用Spring Task首先需要了解corn表达式,通过cor…...
【CSS in Depth 2 精译_087】14.4:CSS 中的浮动特效以及在文字环绕中的应用 + 14.5:本章小结
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 14 章 蒙版、形状与剪切】 ✔️ 14.1 滤镜 14.1.1 滤镜的类型14.1.2 背景滤镜 14.2 蒙版 14.2.1 带渐变效果的蒙版特效14.2.2 基于亮度来定义蒙版14.2.3 其他蒙版属…...
探索 Python编程 调试案例:计算小程序中修复偶数的bug
在 学习Python 编程的过程里,会遇到各种各样的bug。而修复bug调试代码就像是一场充满挑战的侦探游戏。每一个隐藏的 bug 都是谜题,等待开发者去揭开真相,让程序可以顺利运行。今天,让我们通过一个实际案例,深入探索 Py…...
探索 CI/CD 工具的力量
CI/CD 工具是什么? CI/CD 工具是开发者的“生产力加速器”。它通过自动化代码构建、测试、部署等流程,消除了繁琐的手动操作,确保开发和运维的无缝衔接。借助这些工具,开发者不仅能够更快地发布产品,还能更早发现问题…...
MySQL和Oracle的区别
MySQL和Oracle的区别 MySQL是轻量型数据库,并且免费,没有服务恢复数据。 Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。 1.对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交࿰…...
亚马逊云科技 re:Invent 2024重磅发布!Amazon Bedrock Data Automation 预览版震撼登场
AWS re:Invent 2024 已圆满落幕! 在本次大会中,隆重推出了一项全新功能: Amazon Bedrock Data Automation(预览版)震撼登场! New Amazon Bedrock capabilities enhance data processing and retrieval | …...
SQL语句练习
阅读《SQL必知必会》(第五版)然后结合往常表做的练习记录 这里使用的数据库时sqlite3,使用的工具时navicat 表资源链接https://wenku.baidu.com/view/349fb3639b6648d7c1c74652.html 表录入后如上图所示。后面如果有多张表之间的操作,在引入…...
保姆级教程Docker部署RabbitMQ镜像
目录 1、创建挂载目录 2、运行RabbitMQ容器 3、Compose运行RabbitMQ容器 4、开启界面插件 5、查看RabbitMQ运行状态 6、常见问题处理 1、创建挂载目录 # 创建宿主机rabbitMQ挂载目录 sudo mkdir -p /data/docker/rabbitmq/log# 修改log目录权限 sudo chmod 777 /data/do…...
P6打卡—Pytorch实现人脸识别
🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 1.检查GPU import torch import torch.nn as nn import matplotlib.pyplot as plt import torchvisiondevicetorch.device("cuda" if torch.cuda.is_…...
clickhouse-介绍、安装、数据类型、sql
1、介绍 ClickHouse是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),使用C语言编写,主要用于在线分析处理查询(OLAP),能够使用SQL查询实时生成分析数据报告。 OLAP(On-Line A…...
基于单片机的智能婴儿床监护系统多功能婴儿床摇篮系统
功能介绍 以STM32单片机为控制核心蓝牙传输控制可以进行哭闹检测、尿床检测、音乐播放、语音提醒、哭闹时可以进行摇床有不同的模式自动模式和睡眠模式 实物可做,其他功能也可以 电路图 PCB 源代码 u8 Temperature_High; //室内温度高阈值 u8 Temperature_…...
微服务??
1、微服务架构的定义是什么? 微服务架构是一种将应用程序拆分为多个小型、独立服务的架构风格,每个服务专注于完成特定功能,通过轻量级通信协议(如HTTP/REST、gRPC)进行协作。 2、微服务和单体架构有哪些主要区别&am…...
14-zookeeper环境搭建
0、环境 java:1.8zookeeper:3.5.6 1、下载 zookeeper下载点击这里。 2、安装 下载完成后解压,放到你想放的目录里。先看一下zookeeper的目录结构,如下图: 进入conf目录,复制zoo_sample.cfg࿰…...
计算机网络 八股青春版
什么是HTTP?HTTP和HTTPS的区别 HTTP HTTP是超文本运输协议,是一种无状态(每次请求都是独立的)的应用层协议。用于在客户端和服务器之间传输超文本数据(如HTML文件)。默认端口是80数据以明文形式传输&#…...
快速解决oracle 11g中exp无法导出空表的问题
在一些生产系统中,有些时候我们为了进行oracle数据库部分数据的备份和迁移,会使用exp进行数据的导出。但在实际导出的时候,我们发现导出的时候,发现很多空表未进行导出。今天我们给出一个快速解决该问题的办法。 一、问题复现 我…...
Unity 6 Preview(预览版)新增功能
原文链接:Unity - 手册:Unity 6 预览版中的新增功能 目录 原文链接:Unity - 手册:Unity 6 预览版中的新增功能 编辑器和工作流程 UI 工具包 实体 图形 URP HDRP (HDRP) 多人游戏 游戏对象的 Netc…...
Halcon单相机+机器人=眼在手上#标定心得
首先,这个标定板肯定是放在我们要作业的工作台上的 目的 **1,得到标定物(工作台)与机器人底座之间的pose转换关系。2,得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1,标定板与机器人底座b…...
Django 模板分割及多语言支持案例【需求文档】-->【实现方案】
Django 模板分割及多语言支持案例 这个案例旨在提供一个清晰的示范,展示如何将复杂的页面分解为多个可复用的模板组件,使代码更加模块化和易于管理。希望这篇案例文章对你有所帮助。 概述 在 Django 项目开发中,使用模板分割和多语言支持能…...
【hackmyvm】Diophante 靶场
1. 基本信息^toc 这里写目录标题 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. knock 3. WordPress利用3.1. wpscan扫描3.2. smtp上传后门 4. 提权4.1. 提权leonard用户4.2. LD劫持提权root 靶机链接 https://hackmyvm.eu/machines/machine.php?vmDiophante 作者…...
基于MATLAB的图像增强
🍑个人主页:Jupiter. 🚀 所属专栏:传知代码 欢迎大家点赞收藏评论😊 目录 一、背景及意义介绍背景图像采集过程中的局限性 意义 二、概述三、代码结构及说明(一)整体结构(二…...
P10425 [蓝桥杯 2024 省 B] R 格式
题目描述: 小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 00 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是: 将浮点数乘以 2^n。四舍五入到最接近的整…...
《软件工程文档攻略:解锁软件开发的“秘籍”》
《软件工程文档攻略:解锁软件开发的“秘籍”》 一、引言(一)简述软件工程文档的重要地位 二、软件文档的分类及作用(一)按形式分类1. 工作表格2. 文档或文件 (二)按产生和使用范围分类1. 开发文…...
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…...
sqlilabs靶场二十一关二十五关攻略
第二十一关 第一步 可以发现cookie是经过64位加密的 我们试试在这里注入 选择给他编码 发现可以成功注入 爆出表名 爆出字段 爆出数据 第二十二关 跟二十一关一模一样 闭合换成" 第二十三关 第二十三关重新回到get请求,会发现输入单引号报错,…...
时间管理系统|Java|SSM|JSP|
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html 5⃣️数据库可…...
长轮询DeferredResult原理
DeferredResult常用来实现客户端长轮询,可以将异步处理的结果在特定时间内(如果设置了超时时间)返回给客户端。 Slf4j RestController RequestMapping("/demo") public class DemoDeferredResult {GetMapping("/deferredResu…...
TouchGFX移植(5)增加触屏驱动
一)增加驱动代码gt9xxx.c和ctiic.c到工程中的BSP目录下: 二)更改触摸文件STM32TouchController.cpp 1)在STM32TouchController.cpp文件中增加: #include “gt9xxx.h” 2)增加gt9xxx_init(); void STM32TouchControlle…...
(九)腾讯cloudstudio(ubuntu)+akiaaa大神 Stable Diffusion整合包 AI绘画教程
一、说明 在网上转了一圈,发现确实akiaaa大神的整合包不错,看看这界面就比我前面的流弊多了,后面我们就要把这个界面一步一步干出来 二、环境准备 这里和前面的一样 (七)腾讯cloudstudioStable-Diffusion-webui AI绘…...
设计模式-访问者设计模式
介绍 访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变个元素的类的前提下定义作用于这些元素的新操作。 问题:在一个机构里面有两种员工,1.Teacher 2.Engineer 员…...
深度学习实战车辆目标跟踪【bytetrack/deepsort】
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对车辆目标数据集进行训练和优化,该数据集包含丰富的车辆目标图像样本…...
lammps中EDGE、INF、NULL等常量的含义
在lammps命令中,有几个比较常见的量:EDGE、INF、NULL,不少初学者不知道什么意思,本文详细介绍一下这几个量的含义及用法。 1. EDGE EDGE表示当前box的边界,常用到需要设置坐标的命令中,如region、fix wall/reflect。 EDGE仅表示当前box边界的坐标值,当box尺寸发生变化后…...
Mono里建立调试C#脚本运行环境
前面已经介绍了怎么样来执行一个嵌入式的脚本框架, 这个框架是mono编写的一个简单的例子。 如果不清楚,可以参考前文: https://blog.csdn.net/caimouse/article/details/144632391?spm=1001.2014.3001.5501 本文主要来介绍一下,我们的C#脚本是长得怎么样的,它大体如下…...
241221面经
1,JVM 的实现中堆、栈和方法区的区别是什么? 堆(Heap) 功能 堆是 JVM 内存中最大的一块,主要用于存储对象实例。无论是通过new关键字创建的对象,还是数组,都在堆上分配内存。它是被所有线程共享…...
【论文复刻】新型基础设施建设是否促进了绿色技术创新的“量质齐升”—来自国家智慧城市试点的证据(C刊《中国人口·资源与环境》
一、数据来源:住建部、国家知识产权局、中国城市统计年鉴,内含原始数据、处理代码和基准回归 二、数据范围: DID 为了延长政策效应估计的时间区间,将住建部公布的首批国家智慧城市作为处理组,非试点城市作为对照组。将…...
libreoffice表格python宏教程 一
一、安装python宏扩展 LibreOffice自带了一个宏编辑器,但是只能用basic语言,无法用Python。 所以,我们必须在单独的编辑器中编写Python代码。 需要安装apso扩展,此扩展可以创建删除管理python宏文件,同时还能设置偏好…...
C/C++语言基础--C++STL库之仿函数、函数对象、bind、function简介
本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 STL无疑是C史上一个重要的发明,未来我将更新STL有关的知识点,入门绝对够了(看目录就知道了👀)这是第二篇,讲仿函数C语言后面也会继续更新知识点,如…...
前端导出PDF的组件及方法
前端导出PDF的组件及方法 在Web应用程序中,导出PDF文件是一项常见的需求。无论是为了打印、分享还是存档,能够将网页内容转换为PDF格式都非常有用。幸运的是,前端开发者有多种方法和组件可以实现这一功能。在本文中,我们将详细介…...
大数据-256 离线数仓 - Atlas 数据仓库元数据管理 正式安装 启动服务访问 Hive血缘关系导入
点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop࿰…...
水文知识图谱构建-学习+代码
文章目录 水文模型知识图谱构建与应用(核心)面向水利防汛抢险的知识图谱构建与应用知识图谱在水利工程中的构建与应用代码 水文模型知识图谱构建与应用(核心) 水文模型知识图谱构建与应用 题目:水文模型知识图谱构建…...
python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django
windows首先安装rabbitmq 点击参考安装 1、环境介绍 Python 3.10.16 其他通过pip安装的版本(Django、pika、celery这几个必须要有最好版本一致) amqp 5.3.1 asgiref 3.8.1 async-timeout 5.0.1 billiard 4.2.1 celery 5.4.0 …...
clickhouse优化记录
一、注重使用分区键来加快查询 在大数据量的情况下,如果查询语句中,可以使用分区键来进行查询,可以极大缩小数据的查询范围,加快查询速度。 二、使用order by的列,适用最左前缀匹配原则 比如表的结构是 order by(id…...
RabbitMQ如何构建集群?
大家好,我是锋哥。今天分享关于【RabbitMQ如何构建集群?】面试题。希望对大家有帮助; RabbitMQ如何构建集群? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中,集群(Cluster&#x…...
Python解压tar压缩文件
import tarfile import os# 解压文件def untar(self, log_tar_file, destination_dir):# 打开tar文件tar_file_path for tar_file_path in glob.glob(os.path.join(log_tar_file, **/*.tar), recursiveTrue):print(日志压缩文件:,tar_file_path)if ! tar_file_pat…...
Mac升级macOS 15 Sequoia后,无法ssh连接本地虚拟机
现象 macOS 15后,无法ssh连接本地启动的虚拟机,提示错误: No route to host,也ping不通。包括UTM、Parallels Desktop这两个虚拟机软件。之前都是没问题的,通过一些简单排查,目前没发现什么问题。 在虚拟…...
Unity录屏插件-使用Recorder录制视频
目录 1.Recorder的下载 2.Recorder面板 2.1常规录制属性 2.2录制器配置 2.2.1添加录制器 2.2.2配置Input属性 2.2.3配置 Output Format 属性 2.2.4配置 Output File 属性 3.Recorder的使用 3.1录制Game View视频 3.1.1Recorder配置与场景搭建 3.1.2开始录制 3.1.3…...
[ESP]从零开始的Arduino IDE安装与ESP环境配置教程
一、前言 最近也是在比赛方面比较忙,没有更多的时间和精力去更新长文章了。这几周都更倾向于环境搭建的教程,这类教程写起来确实方便,也不怎么费时间,一个下午基本可以搞定,哈哈,我保证不是在为自己想摆烂找…...
重拾设计模式--状态模式
文章目录 状态模式(State Pattern)概述状态模式UML图作用:状态模式的结构环境(Context)类:抽象状态(State)类:具体状态(Concrete State)类&#x…...
2024年全球办公键盘行业总体规模、主要企业国内外市场占有率及排名
根据QYResearch研究团队调研统计,2023年全球办公键盘市场销售额达到了 亿元,预计2030年将达到 亿元,年复合增长率(CAGR)为 %(2024-2030)。中国市场在过去几年变化较快,2023年市场规模…...
ThreadLocal用法详解
ThreadLocal 是 Java 中的一个类,它提供了线程局部变量的功能。线程局部变量是线程隔离的,每个使用该变量的线程都有其自己的变量副本,因此每个线程可以操作自己的线程局部变量,而不会和其他线程冲突。 以下是 ThreadLocal 的一些…...