Java 中 ConcurrentHashMap 和 HashMap 能存 null 吗?深挖原理和使用场景

前言

当你使用 HashMapConcurrentHashMap 时,可能会冒出一个经典问题:它们能存储 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 键和值,实际并非如此。记住:ConcurrentHashMapnull 说“不”!

误区 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("键和值均不能为空");
}

七、总结

特性HashMapConcurrentHashMap
允许 null
允许 null
线程安全性
典型使用场景单线程、灵活性需求高多线程、高并发环境

记住这些差异,你就能在项目中更高效地选择合适的 Map 类型。如果你有任何疑问,欢迎留言一起探讨! 😊

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

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

相关文章

0101多级nginx代理websocket配置-nginx-web服务器

1. 前言 项目一些信息需要通过站内信主动推动给用户&#xff0c;使用websocket。web服务器选用nginx&#xff0c;但是域名是以前通过阿里云申请的&#xff0c;解析ip也是阿里云的服务器&#xff0c;甲方不希望更换域名。新的系统需要部署在内网服务器&#xff0c;简单拓扑图如…

python安装包的几种方法

要安装一个Python包&#xff0c;通常有几种方法&#xff0c;具体取决于包的来源和类型。以下是几种常见的安装方法&#xff1a; 1. 使用pip安装&#xff08;推荐&#xff09; 如果你想要安装的包已经在PyPI&#xff08;Python Package Index&#xff09;上注册&#xff0c;你…

Everything实现,快速搜索文件

最近编写NTFS文件实时搜索工具, 类似 Everything 这样, 翻阅了很多博客, 结果大致如下: 1.分析比较肤浅, 采用USN日志枚举来获取文件记录 速度一言难尽, 因为日志枚举的是全盘所有文件的所有日志, 记录比文件记录还多, 速度当然很慢, 还有的甚至于是 使用 DeviceIoControl 函数…

R 基础运算

R 基础运算 R 是一种广泛使用的统计编程语言&#xff0c;它提供了强大的数据操作和分析功能。基础运算在 R 中非常重要&#xff0c;因为它们是进行更复杂计算和数据分析的基础。本文将详细介绍 R 中的基础运算&#xff0c;包括算术运算、逻辑运算、向量化和矩阵运算。 一、算…

京东大数据治理探索与实践 | 京东零售技术实践

01背景和方案 在当今的数据驱动时代&#xff0c;数据作为关键生产要素之一&#xff0c;其在商业活动中的战略价值愈加凸显&#xff0c;京东也不例外。 作为国内领先的电商平台&#xff0c;京东在数据基础设施上的投入极为巨大&#xff0c;涵盖数万台服务器、数 EB 级存储、数百…

nodejs搭配express网站开发后端接口设计需要注意事项

nodejs搭配express网站开发后端接口设计需要注意事项&#xff01;为了回避一些常见的误区&#xff0c;今天和大家汇总一下&#xff0c;最近我遇到的一些错误信息&#xff0c;虽然都是小问题&#xff0c;但是还是需要分享一下&#xff0c;以免大家再次犯错。 1&#xff1a;第一个…

解决vscode ssh远程连接服务器一直卡在下载 vscode server问题

目录 方法1&#xff1a;使用科学上网 方法2&#xff1a;手动下载 方法3 在使用vscode使用ssh远程连接服务器时&#xff0c;一直卡在下载"vscode 服务器"阶段&#xff0c;但MobaXterm可以正常连接服务器&#xff0c;大概率是网络问题&#xff0c;解决方法如下: 方…

Spring Boot实现OAuth2.0登录实战

一、前言 最近在研究Springboot Vue 的前后端分离框架&#xff0c;刚开始做登录功能&#xff0c;做着做着觉得普通账户密码登录太简单了&#xff0c;决定再加上 GitHub授权 和 人脸识别等多种快捷登录方式。 而GitHub授权登录正好用到了OAuth2.0中最复杂的授权码模式&#xf…

电脑开机提示error loading operating system怎么修复?

前一天电脑还能正常运行&#xff0c;但今天启动时却显示“Error loading operating system”&#xff08;加载操作系统错误&#xff09;。我已经仔细检查了硬盘、接线、内存、CPU和电源&#xff0c;确认这些硬件都没有问题。硬盘在其他电脑上可以正常使用&#xff0c;说明不是硬…

Java web的发展历史

目录 前言&#xff1a; 一.Model I和Model II 1.Model I开发模式 ​编辑 2.Model II开发模式 二. MVC模式 前言&#xff1a; 该篇文章主要介绍了Java web的发展历史&#xff0c;以及MVC相关内容 一.Model I和Model II 1.Model I开发模式 Model1的开发模式是&#xff…

Flink DataStream API 编程指南

(对于Flink的开发,建议使用Java,Scala的支持未来会被移除) DataStream是什么 DataStream API得名于DataStream这个Java类,可以将它们视为可以包含重复项的不可变数据集合。该数据可以是有限的,也可以是无限的,用于处理它们的API是相同的。 DataStream在用法上和普通的…

Intel-ECI之Codesys PLC + Ethercat 远端IO + Codesys IDE编程

目录 一、 准备工作 二、安装Codesys 软件 PLC 三、 使用Codesys IDE 编程测试 CODESYS* 是领先的独立于制造商的 IEC 61131-3 自动化软件&#xff0c;适用于工程控制系统。它用于 Intel Edge Controls for Industrial&#xff08;Intel ECI 或 ECI&#xff09;&#xff0c;…

SQL语句练习

阅读《SQL必知必会》&#xff08;第五版&#xff09;然后结合往常表做的练习记录 这里使用的数据库时sqlite3,使用的工具时navicat 表资源链接https://wenku.baidu.com/view/349fb3639b6648d7c1c74652.html 表录入后如上图所示。后面如果有多张表之间的操作&#xff0c;在引入…

Java游戏开发基础:从零开始制作一个简单的2D游戏

目录 游戏开发概述 开发工具 项目结构 1. 创建游戏窗口 2. 游戏面板 解释&#xff1a; 3. 玩家类 解释&#xff1a; 4. 障碍物类 解释&#xff1a; 5. 游戏循环与碰撞检测 总结 在现代游戏开发中&#xff0c;Java被广泛应用于创建各种类型的游戏&#xff0c;特别是…

【Python】【数据分析】深入探索 Python 数据可视化:Seaborn 可视化库详解

目录 引言一、Seaborn 简介二、安装 Seaborn三、Seaborn 的基本图形3.1 散点图&#xff08;Scatter Plot&#xff09;3.2 线图&#xff08;Line Plot&#xff09;3.3 条形图&#xff08;Bar Plot&#xff09;3.4 箱型图&#xff08;Box Plot&#xff09;3.5 小提琴图&#xff0…

input输入框的placeholder颜色修改(Shadow DOM)

placeholder颜色修改 使用参考说明 https://zh.javascript.info/shadow-dom 查看shadow tree的方法

MacPorts 中安装高/低版本软件方式,以 RabbitMQ 为例

查询信息 这里以 RabbitMQ 为例&#xff0c;通过搜索得到默认安装版本信息&#xff1a; port search rabbitmq-server结果 ~/Downloads> port search rabbitmq-server rabbitmq-server 3.11.15 (net)The RabbitMQ AMQP Server ~/Downloads>获取二进制文件 但当前官网…

Android不可擦除分区写文件恢复出厂设置,无法读写问题

普通应用往不可擦除分区写文件之后&#xff0c;恢复出厂设置 现象&#xff1a;概率性读不到写过之后的文件 12-18 10:57:31.348 7980 7980 W System.err: java.io.FileNotFoundException: /xxx/xxx: open failed: EACCES (Permission denied) 12-18 10:57:31.348 7980 79…

uniApp使用腾讯地图提示未添加maps模块

uniApp使用腾讯地图&#xff0c;打包提示未添加maps模块解决方案 这是报错信息&#xff0c;在标准基座运行的时候是没问题的&#xff0c;但是打包后会提示未添加&#xff0c;可以通过在mainfest里面把地图插件上腾讯地图的key更换高德地图的key&#xff0c;定位服务可以继续用腾…

【人工智能】用Python实现图卷积网络(GCN):从理论到节点分类实战

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 目录 引言图卷积网络理论基础 2.1 图的基本概念2.2 卷积神经网络在图上的扩展2.3 GCN的数学模型GCN的实现 3.1 环境配置3.2 数据集介绍与预处理3.3 模型构建3.4 训练与优化实战:节点分类 4.1 模型训练4.2 结果分…