Java 枚举类 Key-Value 映射的几种实现方式及最佳实践
Java 枚举类 Key-Value 映射的几种实现方式及最佳实践
前言
在 Java 开发中,枚举(Enum)是一种特殊的类,它能够定义一组固定的常量。在实际应用中,我们经常需要为枚举常量添加额外的属性,并实现 key-value 的映射关系。本文将详细介绍 Java 枚举类实现 key-value 映射的多种方式,分析各自的优缺点,并给出实际应用中的最佳实践建议。
一、基础实现方式
1.1 为枚举添加属性和构造方法
最基本的实现方式是为枚举添加 key 和 value 属性,并提供相应的构造方法和访问方法。
public enum Status {ACTIVE("A", "激活状态"),INACTIVE("I", "未激活状态"),PENDING("P", "等待状态");private final String key;private final String value;Status(String key, String value) {this.key = key;this.value = value;}public String getKey() {return key;}public String getValue() {return value;}
}
使用示例:
Status active = Status.ACTIVE;
System.out.println("Key: " + active.getKey() + ", Value: " + active.getValue());
优点:
- 实现简单直观
- 无需额外数据结构支持
缺点:
- 查找效率低(需要遍历所有枚举值)
二、高效查找实现方式
2.1 使用静态 Map 缓存
为了提高查找效率,可以使用静态 Map 来缓存 key 与枚举实例的映射关系。
import java.util.HashMap;
import java.util.Map;public enum Status {ACTIVE("A", "激活状态"),INACTIVE("I", "未激活状态");private final String key;private final String value;private static final Map<String, Status> BY_KEY = new HashMap<>();static {for (Status s : values()) {BY_KEY.put(s.key, s);}}Status(String key, String value) {this.key = key;this.value = value;}public static Status fromKey(String key) {return BY_KEY.get(key);}public static String getValueByKey(String key) {Status status = fromKey(key);return status != null ? status.value : null;}// getters...
}
优点:
- 查找效率高(O(1)时间复杂度)
- 适合枚举值较多的情况
缺点:
- 需要额外的内存空间存储 Map
- 静态初始化可能增加类加载时间
2.2 使用 Java 8 Stream API
Java 8 引入了 Stream API,我们可以利用它来实现简洁的查找逻辑。
public static Status fromKeyStream(String key) {return Arrays.stream(Status.values()).filter(status -> status.getKey().equals(key)).findFirst().orElse(null);
}
优点:
- 代码简洁
- 无需额外数据结构
缺点:
- 每次查找都需要遍历(性能不如 Map 缓存)
- 适合枚举值较少或查找不频繁的场景
三、进阶技巧与最佳实践
3.1 处理 null 和不存在的情况
在实际应用中,我们需要考虑 key 为 null 或不存在的情况。
public static Status fromKeySafely(String key) {if (key == null) {return null;}return BY_KEY.get(key);
}public static String getValueByKeySafely(String key) {Status status = fromKeySafely(key);return status != null ? status.getValue() : "UNKNOWN";
}
3.2 不可变 Map 实现
如果希望 Map 不可变,可以使用 Collections.unmodifiableMap:
private static final Map<String, Status> BY_KEY;
static {Map<String, Status> map = new HashMap<>();for (Status s : values()) {map.put(s.key, s);}BY_KEY = Collections.unmodifiableMap(map);
}
3.3 枚举与接口结合
可以让枚举实现接口,提供更灵活的设计:
public interface KeyValueEnum<K, V> {K getKey();V getValue();
}public enum Status implements KeyValueEnum<String, String> {// 枚举实现...
}
四、性能对比
下表比较了不同实现方式的性能特点:
实现方式 | 时间复杂度 | 空间复杂度 | 适用场景 |
---|---|---|---|
基础实现 | O(n) | O(1) | 枚举值少,查找不频繁 |
静态 Map 缓存 | O(1) | O(n) | 枚举值多,查找频繁 |
Stream API | O(n) | O(1) | Java8+,代码简洁优先 |
五、实际应用示例
5.1 在 Spring Boot 中的应用
结合 Spring Boot,我们可以将枚举与 REST API 更好地结合:
@Getter
public enum ErrorCode implements KeyValueEnum<Integer, String> {SUCCESS(200, "成功"),NOT_FOUND(404, "资源不存在"),SERVER_ERROR(500, "服务器错误");private final Integer key;private final String value;// 构造方法等...
}@RestController
public class ApiController {@GetMapping("/errors/{code}")public ResponseEntity<String> getErrorMessage(@PathVariable Integer code) {return Arrays.stream(ErrorCode.values()).filter(e -> e.getKey().equals(code)).findFirst().map(e -> ResponseEntity.ok(e.getValue())).orElse(ResponseEntity.notFound().build());}
}
5.2 与数据库交互
枚举与数据库值转换的常见模式:
@Converter(autoApply = true)
public class StatusConverter implements AttributeConverter<Status, String> {@Overridepublic String convertToDatabaseColumn(Status status) {return status != null ? status.getKey() : null;}@Overridepublic Status convertToEntityAttribute(String key) {return Status.fromKey(key);}
}
六、总结
- 小型枚举:使用基础实现即可,保持代码简单
- 大型枚举或高频查找:推荐使用静态 Map 缓存方式
- Java8+环境:可以考虑使用 Stream API 实现简洁代码
- 生产环境:务必处理 null 和不存在的情况,考虑使用不可变 Map
枚举的 key-value 映射是 Java 开发中的常见需求,选择适合的实现方式可以显著提高代码的可读性和性能。希望本文介绍的各种方法和最佳实践对您有所帮助。
扩展思考: 如何实现双向查找(通过 key 找 value,通过 value 找 key)?读者可以尝试实现一个双向查找的枚举工具类。
相关文章:
Java 枚举类 Key-Value 映射的几种实现方式及最佳实践
Java 枚举类 Key-Value 映射的几种实现方式及最佳实践 前言 在 Java 开发中,枚举(Enum)是一种特殊的类,它能够定义一组固定的常量。在实际应用中,我们经常需要为枚举常量添加额外的属性,并实现 key-value 的映射关系。本文将详细…...
JavaScript instanceof 运算符全解析
JavaScript instanceof 运算符全解析 核心语义: 判断一个对象(object)是否属于某个构造函数(constructor)或类的实例,基于原型链(prototype chain)实现类型检测。 一、JavaScript 中的基础用法 1. 语法结构 object instanceof constructor 返回值:布尔值(true/fal…...
问题大集09-如何实现vite创建的react项目的配置别名路径@
(1)如何实现vite创建的react项目的配置别名路径 1)直接修改 Vite 配置文件 ①打开项目根目录下的 vite.config.js 文件(如果没有则新建),添加 resolve.alias 配置(新增resolve部分)…...
鸿蒙开发_TS快速入门_TS中模块化操作_模块的导入导出---纯血鸿蒙HarmonyOS5.0工作笔记008
然后我们再来看鸿蒙中的模块如何导入导出。 其实就跟Java中的import是一个意思的。 只不过我们如果想把一个类中的某个方法导入到另一个类中, 那么首先要在这个类中去导出这个方法。 可以看到导出的关键字是export。 然后导入的关键字是import。 然后我们写个例子去看一下,…...
算法设计与分析之“分治法”
分治法(Divide and Conquer)是一种高效的算法设计策略,其核心思想是将复杂问题分解为多个子问题,递归求解后再合并结果。以下是分治法的详细介绍: 一、分治法的基本步骤 分治法遵循以下三步流程: 分解&…...
java 静态内部类
java 静态内部类 一、位置二、特点三、静态内部类的实例化四、代码示例一:演示特点一五、代码示例二:演示特点二六、代码实例三:演示特点三七、代码实例四:演示特点四 文章同步更新(更好的排版):…...
Axure疑难杂症:完美解决文本框读取、赋值、计数(玩转文本框)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:玩转文本框 主要内容:文本框读取、赋值、验证、计数 应用场景:验证码、文本限制、文本取值、文本赋值等场景 案例展示&…...
Python数据可视化-第2章-使用matplotlib绘制简单图表
环境 开发工具 VSCode库的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本书为《Python数据可视化》一书的配套内容,本章为第2章 使用matplotlib绘制简单图表 本文主要介绍了折线图、柱形图或堆积柱形图、条形图或堆积条形图、堆积面积图、直方图、饼图或…...
国产系统服务器识别不到SATA盘
在使用浪潮、海光、华三等系列服务器安装操作系统的时候提示没有足够的存储空间,其实是有两块512的SATA硬盘的,但是他没有识别到。 需要给硬盘做raid存储阵列才能让系统识别到他,下面是在BIOS中配置RAID的方法。 1、重启机器,按下…...
解决小程序video控件在真机和上线后黑屏不播放问题
小程序上线后,mp4格式的视频无法点击是黑屏,但是测试得时候在微信开发者工具中能够打开正常播放 原因:编码格式不能是vp9 微信开发者工具本地设置中把这个打开勾选。 排查:可以换一个视频尝试能不能真机播放,如果能&a…...
Vue3编译器深度解析:从模板编译到极致性能优化
一、编译技术架构演进 1.1 Vue2到Vue3编译架构升级 1.2 编译阶段性能基准对比 优化项Vue2编译耗时Vue3编译耗时性能提升模板解析速度12ms/千节点3ms/千节点75%AST遍历速度8ms/层级2ms/层级68%代码生成速度15ms/组件4ms/组件73%内存占用峰值84MB32MB62% 二、模板编译核心过程 …...
Google Gemini 2.0 网页抓取真丝滑
网页抓取从未如此简单——这一切都要归功于谷歌突破性的多模态实时API Gemini 2.0 借助这个工具,你可以毫不费力地从任何网页提取数据,无论页面结构多么复杂、内容多么杂乱无章,或是需要提取非常特定的信息。 今天,我将通过自己实…...
Leetcode-100 二分查找常见操作总结
二分查找常见操作总结 1. 基本二分查找 目标: 在有序数组 nums 中查找 target 的索引(如果存在)。 适用场景: 需要在 有序数组 中查找某个特定元素。适用于无重复元素的情况。 示例: 输入 nums [1, 2, 3, 4, 5], target 3,输出 2。 d…...
Android: Handler 的用法详解
Android 中 Handler 的用法详解 Handler 是 Android 中用于线程间通信的重要机制,主要用于在不同线程之间发送和处理消息。以下是 Handler 的全面用法指南: 一、Handler 的基本原理 Handler 基于消息队列(MessageQueue)和循环器(Looper)工作ÿ…...
第149场双周赛:找到字符串中合法的相邻数字、重新安排会议得到最多空余时间 Ⅰ、
Q1、找到字符串中合法的相邻数字 1、题目描述 给你一个只包含数字的字符串 s 。如果 s 中两个 相邻 的数字满足以下条件,我们称它们是 合法的 : 前面的数字 不等于 第二个数字。两个数字在 s 中出现的次数 恰好 分别等于这个数字本身。 请你从左到右…...
深入解析Translog机制:Elasticsearch的数据守护者
一、为什么需要Translog? Elasticsearch的数据写入流程是先写入内存缓冲区,然后定期刷新到磁盘生成Lucene分段。由于内存数据易失性,若在刷新前发生宕机,未持久化的数据将永久丢失。Translog的诞生正是为了解决这一数据可靠性问题…...
音视频入门基础:MPEG2-TS专题(25)——通过FFmpeg命令使用UDP发送TS流
音视频入门基础:MPEG2-TS专题系列文章: 音视频入门基础:MPEG2-TS专题(1)——MPEG2-TS官方文档下载 音视频入门基础:MPEG2-TS专题(2)——使用FFmpeg命令生成ts文件 音视频入门基础…...
3、nFR52xx蓝牙学习(点亮第一个LED灯)
一、点灯代码: led.h文件 #ifndef __LED_H #define __LED_H#include "nrf52840.h"#define LED_0 NRF_GPIO_PIN_MAP(0,13) #define LED_1 NRF_GPIO_PIN_MAP(0,14) #define LED_2 NRF_GPIO_PIN_MAP(0,15) #define LED_3 …...
符号秩检验
内容来源 非参数统计(第2版) 清华大学出版社 王星 褚挺进 编著 符号秩检验 在符号检验的基础上,增加了数据绝对值大小的信息 检验统计量 用一个简单的例子来说明 样本数据 X i , i 1 , ⋯ , 6 X_i,i1,\cdots,6 Xi,i1,⋯,6 如下 X …...
制造业数字化转型:流程改造先行还是系统固化数据?基于以MTO和MTS的投资回报分析
1. 执行摘要 制造业正经历一场深刻的数字化转型,企业面临着先进行流程改造以优化运营,还是直接上线系统以固化数据的战略选择。本文深入分析了以销定产(MTO)和以产定销(MTS)两种主要生产模式下,…...
python相关笔记
一。 is和的区别 1.is看的是发票逻辑地址,用来判断两个变量是否引用同一个对象,is关注的是‘身份’ 2.判断两个对象是否具有相同的值,关注的是内容是否相等,也即值是否相等。 3. if x is None: print(x is None")...
C++(匿名函数+继承+多态)
#include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sstream> #include <vector> #include <memory>using namespace std;// 基类 Weapon class Weapon { protected:int atk; public:Weapon…...
界面架构 - MVVM (Qt)
MVVM MVVM 的主要特点示例示例功能示例代码ViewModel 类(C)主函数入口(main.cpp) QML 文件(main.qml)总结 MVVM(Model-View-ViewModel)架构是一种旨在进一步分离界面和业务逻辑的设计…...
在未归一化的线性回归模型中,特征的尺度差异可能导致模型对特征重要性的误判
通过数学公式来更清晰地说明归一化对模型的影响,以及它如何改变特征的重要性评估。 1. 未归一化的情况 假设我们有一个线性回归模型: y β 0 β 1 x 1 β 2 x 2 ϵ y \beta_0 \beta_1 x_1 \beta_2 x_2 \epsilon yβ0β1x1β2x2ϵ 其…...
【大模型系列篇】大模型基建工程:使用 FastAPI 构建 MCP 服务器
今天我们将使用FastAPI来构建 MCP 服务器,Anthropic 推出的这个MCP 协议,目的是让 AI 代理和你的应用程序之间的对话变得更顺畅、更清晰。FastAPI 基于 Starlette 和 Uvicorn,采用异步编程模型,可轻松处理高并发请求,尤…...
基于微信小程序的智慧乡村旅游服务平台【附源码】
基于微信小程序的智慧乡村旅游服务平台(源码L文说明文档) 目录 4系统设计 4.1系统功能设计 4.2系统结构 4.3.数据库设计 4.3.1数据库实体 4.3.2数据库设计表 5系统详细实现 5.1 管理员模块的实现 5.1.1旅游景点管理…...
llm-universe 踩坑记录
踩坑 云服务器2G不够,因为后面用到内存向量数据库,把数据加载到内存,一个大点的pdf就导致整个服务器崩了。当时可以选择不加载大的文件,自己替换一个小点的pdf 注意点 LLM API.ipynb 这节要注意看下API的含义,了解m…...
【案例】跨境电商企业实践云成本优化,选对平台是关键
某跨境电商企业近年因业务发展迅猛,近年来在全球市场大力拓展业务。然而,伴随其全球化布局的深化,云资源成本逐年攀升,每年在云资源方面的投入超 500万元。庞大的云资源使用量虽支撑了业务的快速发展,但也带来了较高的…...
系统思考与时间管理
时间管理的真正秘诀:主动浪费时间? 巴菲特的私人飞机驾驶员觉得自己不够成功,于是向巴菲特请教应该怎么做。巴菲特让他列出了自己人生中最想实现的25个目标,并按重要程度排序,接着安排时间专注做前五件最重要的事情。…...
洛谷.P1563 [NOIP 2016 提高组] 玩具谜题
P1563 [NOIP 2016 提高组] 玩具谜题 - 洛谷 代码区: #include<algorithm> #include<iostream> #include<cstring> #include<string> #include<vector>using namespace std; const int MAX 1000005; struct PEOPLE {int cx;//0朝内…...
华为面试,机器学习深度学习知识点:
机器学习深度学习知识点: 机器学习一般有哪些分数,对于不同的任务: 分类任务: 准确率(Accuracy):预测正确的样本数占总样本数的比例,公式为 Accuracy TPTNFPFN TPTN ,…...
关于 数据库 UNION 和 UNION ALL 的使用,以及 分库分表环境下多表数据组合后的排序和分页问题的解决方案 的详细说明,并以表格总结关键内容
以下是关于 数据库 UNION 和 UNION ALL 的使用,以及 分库分表环境下多表数据组合后的排序和分页问题的解决方案 的详细说明,并以表格总结关键内容: 1. UNION 和 UNION ALL 的核心区别 1.1 定义与语法 UNION 功能:合并两个或多个 …...
架构设计基础系列:事件溯源模式浅析
图片来源网络,侵权删 1. 引言 1.1 研究背景 传统CRUD模型的局限性:状态覆盖导致审计困难、无法追溯历史。分布式系统复杂性的提升:微服务架构下数据一致性、回滚与调试的需求激增。监管合规性要求:金融、医疗等领域对数…...
虚拟试衣间-云尚衣橱小程序-衣橱管理实现
衣橱管理实现 目标 (Goal): 用户 (User): 能通过 UniApp 小程序上传衣服图片。 后端 (Backend): 接收图片,存到云存储,并将图片信息(URL、用户ID等)存入数据库。 用户 (User): 能在小程序里看到自己上传的所有衣服图片列表。 技术栈细化 (Refined Tech Stack for this Pha…...
蓝桥杯省模赛 台阶方案
问题描述 小蓝要上一个楼梯,楼梯共有 n 级台阶(即小蓝总共要走 n 级)。小蓝每一步可以走 a 级、b 级或 c 级台阶。 请问小蓝总共有多少种方案能正好走到楼梯顶端? 输入格式 输入的第一行包含一个整数 n 。 第二行包含三个整数…...
Socket编程UDP
Socket编程UDP 1、V1版本——EchoServer2、网络命令2.1、ping2.2、netstat2.3、pidof 3、验证UDP——Windows作为client访问Linux4、V2版本——DictServer5、V3版本——简单聊天室 1、V1版本——EchoServer 首先给出EchoServer目录结构:服务器的类我们实现在UdpServ…...
无人机机体结构设计要点与难点!
一、无人机机体结构设计要点 1. 类型与应用场景匹配 固定翼无人机:需优化机翼升阻比,采用流线型机身降低气动阻力(如大展弦比机翼设计)。 多旋翼无人机:注重轻量化框架和对称布局(如四轴/六轴碳纤维机…...
音视频(一)ZLMediaKit搭建部署
前言 一个基于C11的高性能运营级流媒体服务框架 全协议支持H264/H265/AAC/G711/OPUS/MP3,部分支持VP8/VP9/AV1/JPEG/MP3/H266/ADPCM/SVAC/G722/G723/G729 1:环境 ubuntu22.* ZLMediaKit downlaod:https://github.com/ZLMediaKit/ZLMediaKit or https://g…...
实战 | 餐厅点餐小程序技术解析:SpringBoot + UniApp 高效开发指南
🖥️ 一、系统架构概览 1.1 技术选型 为了确保开发效率和系统稳定性,我们采用以下技术栈: 模块技术选型后台服务SpringBoot MyBatis-Plus MySQL用户端(点餐小程序)UniApp(Vue 语法)师傅端&…...
合并相同 patient_id 的 JSON 数据为数组
问题 select patient_id,concat({"itemText":",item_text,","itemValue":",item_value,"}) from hs_patient_groups where active 1;eef41128c47c401abb7f8885a5f9fbdf {"itemText":"旧","itemValue"…...
AI安全:构建负责任且可靠的系统
AI已成为日常生活中无处不在的助力,随着AI系统能力和普及性的扩展,安全因素变得愈发重要。从基础模型构建者到采用AI解决方案的企业,整个AI生命周期中的所有相关方都必须共同承担责任。 为什么AI安全至关重要? 对于企业而言&…...
STM32单片机入门学习——第8节: [3-4] 按键控制LED光敏传感器控制蜂鸣器
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.02 STM32开发板学习——第8节: [3-4] 按键控制LED&光敏传感器控制蜂鸣器 前言开…...
Linux驱动入门——设备树详解
文章目录 一、设备树的引入与作用二、设备树的语法1. Devicetree格式1.1 DTS文件的格式1.2 node的格式1.3 properties的格式 2. dts文件包含dtsi文件3. 常用的属性3.1 #address-cells、#size-cells3.2 compatible3.3 model3.4 status3.5 reg 4. 常用的节点(node)4.1 根节点4.2 …...
Scala集合
Scala集合分为序列Seq、集Set、映射Map,都扩展自Iterable特质,且有可变和不可变版本。不可变集合操作后会返回新对象,可变集合则直接修改原对象。比如数组,不可变数组定义后大小不可变,修改会生成新数组;可…...
阿里云AI Studio 2.0:拖拽搭建企业级智能客服系统
一、平台能力全景 1.1 核心功能矩阵 模块子功能技术指标对话设计可视化流程编排支持50节点类型NLP引擎意图识别准确率行业TOP3(92.6%)知识管理多源数据接入15格式支持渠道对接全渠道覆盖8大平台SDK 1.2 企业级特性 关键优势: 日均对话承…...
java虚拟机---JVM
JVM JVM,也就是 Java 虚拟机,它最主要的作用就是对编译后的 Java 字节码文件逐行解释,翻译成机器码指令,并交给对应的操作系统去执行。 JVM 的其他特性有: JVM 可以自动管理内存,通过垃圾回收器回收不再…...
您的LarkXR专属顾问上线了!平行云官网新增 AI 小助手,手册同步升级!
遇到LarkXR技术问题?还在手动翻文档? Paraverse平行云官网双升级——AI小助手实时答疑 用户手册智能检索! 助您快速定位解决方案,效率全面提升! < 01 > AI 小助手—— 您的 LarkXR 智能顾问 欢迎我们的新成员…...
推导Bias² + Variance + σ²_ε
问题的背景 我们有一个真实函数 f ( x ) f(x) f(x) 和基于训练数据 D D D 训练得到的模型 f ^ ( x ; D ) \hat{f}(x;D) f^(x;D)。对于任意输入 x x x: y y y 是真实的观测值,定义为 y f ( x ) ϵ y f(x) \epsilon yf(x)ϵ,其中 …...
javaSE知识梳理(一)
一.面向对象编程 1.面向对象的基本元素:类(class)和对象 ①类的声明 语法格式: [修饰符] class 类名{属性声明;方法声明; } ②对象的创建(new) 语法格式: //方式1:给创建有名对象 类名 对象名 new 类名();//方式2࿱…...
k8s statefulset pod重启顺序
在 Kubernetes 中,StatefulSet 的 Pod 重启顺序由以下规则和机制决定: 1. StatefulSet 的核心设计原则 StatefulSet 旨在管理有状态应用,其核心特性包括: 稳定的唯一标识:Pod 名称格式为 <statefulset-name>-&…...