java查询枚举_Java枚举的反向查找
java的枚举常常被用来替代常量值,每个枚举值代表一个特定的常数。
在反序列化时有常常需要用到常数到枚举的转换,这就涉及到枚举的反向查找。
1、从枚举名反向查找枚举
这种方法是最先使用也最为简便的
可以用到枚举的静态方法valueOf(String
name)
valueOf方法为内置方法,使用简便,但在查找不到枚举时会抛出异常。
熟悉异常的同学可能知道异常抛出时,需要收集虚拟机的调用堆栈上下文信息,对性能影响较大。
使用时,常常需要使用这么一个反序列化查找方法
E
find(String name, E defaultValue),在查找不到时能够返回一个默认值而不是抛出异常
2、从枚举值所包含的描述值反向查找枚举
例如这种枚举定义
public enum SomeEnum{
A("ADes", 1),
B("BDes", 2),
unknown("UNKNWONDes", 3);
private string des;
private int order;
private SomeEnum(string des, int order){
this.des = des;
this.order = order;
}
}
此时可以在枚举类中增加一个HashMap,并在类加载时初始化好。
public enum SomeEnum{
A("ADes"),
B("BDes"),
unknown("UNKNWONDes");
private string des;
private static final map lookup = new hashmap();
static {
for(SomeEnum e : EnumSet.allOf(SomeEnum.class)){
lookup.put(e.des, e);
}
}
private SomeEnum(string des){
this.des = des;
}
public static SomeEnum find(string des, SomeEnum defaultValue){
SomeEnum value = lookup.get(des);
if(value == null){
return defaultValue;
}
return value;
}
}
3、进一步,如果枚举中有多个描述值,并且描述值类型不一样
这时初始化代码和查找代码需要写多遍。
public enum SomeEnum{
A("ADes", 1),
B("BDes", 2),
unknown("UNKNWONDes", 3);
private string des;
private int order;
private static final map lookup = new hashmap();
private static final map lookup_int = new hashmap();
static {
for(SomeEnum e : EnumSet.allOf(SomeEnum.class)){
lookup.put(e.des, e);
lookup_int.put(e.order, e);
}
}
private SomeEnum(string des, int order){
this.des = des;
this.order = order;
}
public static SomeEnum find(string des, SomeEnum defaultValue){
SomeEnum value = lookup.get(des);
if(value == null){
return defaultValue;
}
return value;
}
public static SomeEnum find(int order, SomeEnum defaultValue){
SomeEnum value = lookup_int.get(order);
if(value == null){
return defaultValue;
}
return value;
}
}
不少代码有重复,
枚举类需要自己实现反向查找映射关系在HashMap中的初始化。
根据DRY原则,重复代码地方一般都有一定的坏味道。
4、改进
枚举的反向查找其实只需关注两件事情,
a 提供枚举值描述到枚举值的映射
b 能从枚举值描述查找到枚举值,查找不到能提供默认值
据此,可以提炼出枚举反向查找的帮助类:
public class EnumFindHelper, K> {
protected Map map = new HashMap();
public EnumFindHelper(Class clazz, EnumKeyGetter keyGetter) {
try {
for (T enumValue : EnumSet.allOf(clazz)) {
map.put(keyGetter.getKey(enumValue), enumValue);
}
} catch (Exception e) {
//eror handler
}
}
public T find(K key, T defautValue) {
T value = map.get(key);
if (value == null) {
value = defautValue;
}
return value;
}
}
这里需要一个接口定义:
public static interface EnumKeyGetter, K> {
K getKey(T enumValue);
}
查找帮助类EnumFindHelper构造时需要EnumKeyGetter来提供枚举值到枚举类型的的对应关系。
定义枚举类时实现EnumKeyGetter接口,并传入EnumFindHelper。
修改后的枚举定义可能为:
public enum SomeEnum{
A("ADes", 1),
B("BDes", 2),
unknown("UNKNWONDes", 3);
private String des;
private int order;
private SomeEnum(string des, int order){
this.des = des;
this.order = order;
}
static final EnumFindHelper desptHelper = new EnumFindHelper(
SomeEnum.class, new DesptGetter());
static final EnumFindHelper orderHelper = new EnumFindHelper(
SomeEnum.class, new OrderKeyGetter());
static class DesptGetter implements EnumKeyGetter {
@Override
public String getKey(SomeEnum enumValue) {
return enumValue.des;
}
}
static class OrderKeyGetter implements EnumKeyGetter {
@Override
public String Integer(SomeEnum enumValue) {
return enumValue.order;
}
}
public static SomeEnum find(string despt, SomeEnum defaultValue){
return desptHelper.find(des, defaultValue);
}
public static SomeEnum find(int order, SomeEnum defaultValue){
return orderHelper.find(des, defaultValue);
}
}
EnumFindHelper内部类的定义有些繁琐,不过java8之后用lambda实现后会简便一些。
5 总结
每个枚举类的反向查找功能委托一个帮助类来实现,从枚举类的构造上来看,比较类似GOF的桥接模式。
而从委托类的实现查找功能来看,需要一个EnumKeyGetter接口,每种不同的接口实现不同的查找方式,有根据描述字符查找,有根据枚举顺序值查找。
这又有些类似GOF的策略模式。
当然不需要去纠结于哪种设计模式,代码的设计就是要求代码不冗余,功能的重用,依赖的解耦。
上面的设计中:
1)利用EnumFindHelper做到枚举查找的算法重用,利用一个map提供枚举描述到枚举值的查找。
2)EnumFindHelper初始化时需要构造好查找用的map,所以会依赖于具体的枚举定义。
这里抽象出EnumKeyGetter,EnumFindHelper由依赖于具体的枚举类改为依赖于EnumKeyGetter接口,在构造时注入了EnumKeyGetter的实现。
这么看起来是不是有些DPI(依赖注入)的感觉?!
(转载请注明出处)
java查询枚举_Java枚举的反向查找相关推荐
- java的枚举_Java 枚举
Java 枚举 知识点 概念 enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum 关键字修饰的类型就是枚举类型.形式如下: enum Col ...
- java enum 随机_Java 枚举(enum)
1.枚举(enum) enum是一个特殊的类,代表一组常量(不可更改的变量,如,final变量). 要创建enum,请使用enum关键字(而不是类或接口),并用逗号分隔常量.请注意,它们应使用大写字母 ...
- java return用法_Java枚举的高级用法之多键值的映射使用
枚举Enum单映射使用 做Java的各位仁兄姐妹都知道,Java通过HashMap,以及枚举提供了方便的K-V映射功能,例如 枚举单映射使用 但是如果遇到多个键值映射,例如K-K-V的形式怎么办呢?可 ...
- c enum能像java一样吗_Java枚举替代我如何做到这一点?
通过编码MIDI处理程序来自学Java.程序需要做的一件事是在MIDI音符编号及其对应的紧凑字符串表示形式之间来回转换.我看过使用枚举设置,但是由于命名限制,您无法执行类似的操作 c-1, c#-1, ...
- java enum 变量_java枚举使用详解
package com.ljq.test; /** * 枚举用法详解 * * @author jiqinlin * */ public class TestEnum { /** * 普通枚举 * * ...
- java 枚举内嵌枚举_Java枚举益智游戏
java 枚举内嵌枚举 假设我们有以下代码: enum Case {CASE_ONE,CASE_TWO,CASE_THREE;private static final int counter;priv ...
- java 入参 是 枚举_java 枚举 参数传递
展开全部 这样做是不行的,原因是:Java中的对象实例化都是在堆中,如果是普通的类实例变量,比如在方法636f707962616964757a686964616f313333376166371中定义的 ...
- 什么是java枚举_java枚举的概念是什么?有哪些方法?
java中关于枚举的知识点也是非常多的,枚举中的知识点可以细分成很多部分,想要全部掌握还是比较花费时间的.今天主要来简述一下枚举的一些基本的概念和方法,一起来了解一下吧. 首先说一下,枚举的概念. e ...
- java枚举怎么遍历,java遍历枚举_java枚举的两种遍历方法
摘要 腾兴网为您分享:java枚举的两种遍历方法,余额宝,永安期货,易视云3,小睡眠等软件知识,以及幻想三国志4外传,损益表表格,2018微信最新的版本,贺卡,手机mp3格式转换器,cf挂无毒,火炬之 ...
最新文章
- 运行Android应用时提示ADB是否存在于指定路径问题
- 北邮OJ 2016网预 - Saber's Conjecture
- jdbc详解:1、创建数据库connection连接
- python中值滤波介绍_Python 实现中值滤波、均值滤波的方法
- HWM和delete,drop,truncate的关系
- 学习日报 1026 使用属性升级MyBank
- golang时间类型转换
- mysql 存储过程 转义_mysql存储过程中的 sql语句符号问题
- EasyUI datebox 设置为按月选择
- Postgresql Hot_Standby 流复制 基于Linux 对postgresql 和 linux 会基本的操作
- 多目标追踪综述阅读(2021)
- 用JSDoc生成js文档
- 区块链入门导航-磨链社区
- python中try怎么用_python中的try的用法,try 的用法?,英文try的用法
- 【Meta Learning学习笔记】Meta Learning详解
- 机器学习中数据缺失值处理方法
- 【研报】医美行业产业投资宝典:颜值新经济,美丽无止境——附下载链接
- 内向的孩子学医好还是学计算机好,什么性格适合学医 哪种人不适合学医
- 【MAUI】条形码,二维码扫描功能
- python基础知识验证哥德巴赫猜想