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枚举的反向查找相关推荐

  1. java的枚举_Java 枚举

    Java 枚举 知识点 概念 enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum 关键字修饰的类型就是枚举类型.形式如下: enum Col ...

  2. java enum 随机_Java 枚举(enum)

    1.枚举(enum) enum是一个特殊的类,代表一组常量(不可更改的变量,如,final变量). 要创建enum,请使用enum关键字(而不是类或接口),并用逗号分隔常量.请注意,它们应使用大写字母 ...

  3. java return用法_Java枚举的高级用法之多键值的映射使用

    枚举Enum单映射使用 做Java的各位仁兄姐妹都知道,Java通过HashMap,以及枚举提供了方便的K-V映射功能,例如 枚举单映射使用 但是如果遇到多个键值映射,例如K-K-V的形式怎么办呢?可 ...

  4. c enum能像java一样吗_Java枚举替代我如何做到这一点?

    通过编码MIDI处理程序来自学Java.程序需要做的一件事是在MIDI音符编号及其对应的紧凑字符串表示形式之间来回转换.我看过使用枚举设置,但是由于命名限制,您无法执行类似的操作 c-1, c#-1, ...

  5. java enum 变量_java枚举使用详解

    package com.ljq.test; /** * 枚举用法详解 * * @author jiqinlin * */ public class TestEnum { /** * 普通枚举 * * ...

  6. java 枚举内嵌枚举_Java枚举益智游戏

    java 枚举内嵌枚举 假设我们有以下代码: enum Case {CASE_ONE,CASE_TWO,CASE_THREE;private static final int counter;priv ...

  7. java 入参 是 枚举_java 枚举 参数传递

    展开全部 这样做是不行的,原因是:Java中的对象实例化都是在堆中,如果是普通的类实例变量,比如在方法636f707962616964757a686964616f313333376166371中定义的 ...

  8. 什么是java枚举_java枚举的概念是什么?有哪些方法?

    java中关于枚举的知识点也是非常多的,枚举中的知识点可以细分成很多部分,想要全部掌握还是比较花费时间的.今天主要来简述一下枚举的一些基本的概念和方法,一起来了解一下吧. 首先说一下,枚举的概念. e ...

  9. java枚举怎么遍历,java遍历枚举_java枚举的两种遍历方法

    摘要 腾兴网为您分享:java枚举的两种遍历方法,余额宝,永安期货,易视云3,小睡眠等软件知识,以及幻想三国志4外传,损益表表格,2018微信最新的版本,贺卡,手机mp3格式转换器,cf挂无毒,火炬之 ...

最新文章

  1. 运行Android应用时提示ADB是否存在于指定路径问题
  2. 北邮OJ 2016网预 - Saber's Conjecture
  3. jdbc详解:1、创建数据库connection连接
  4. python中值滤波介绍_Python 实现中值滤波、均值滤波的方法
  5. HWM和delete,drop,truncate的关系
  6. 学习日报 1026 使用属性升级MyBank
  7. golang时间类型转换
  8. mysql 存储过程 转义_mysql存储过程中的 sql语句符号问题
  9. EasyUI datebox 设置为按月选择
  10. Postgresql Hot_Standby 流复制 基于Linux 对postgresql 和 linux 会基本的操作
  11. 多目标追踪综述阅读(2021)
  12. 用JSDoc生成js文档
  13. 区块链入门导航-磨链社区
  14. python中try怎么用_python中的try的用法,try 的用法?,英文try的用法
  15. 【Meta Learning学习笔记】Meta Learning详解
  16. 机器学习中数据缺失值处理方法
  17. 【研报】医美行业产业投资宝典:颜值新经济,美丽无止境——附下载链接
  18. 内向的孩子学医好还是学计算机好,什么性格适合学医 哪种人不适合学医
  19. 【MAUI】条形码,二维码扫描功能
  20. python基础知识验证哥德巴赫猜想

热门文章

  1. 变压器 线圈 绕紧绕松的影响
  2. 海康威视2022面经(含内推码)
  3. 报告,掘金翻译计划招募志愿者啦
  4. AMD开源显卡光追分析器,可提升游戏开发性能,网友:A卡战未来
  5. React 核心开发者 Dan Abramov 访谈实录
  6. python字节数组如何使用?
  7. 追女孩子非常火的一片文章
  8. 2021年高考成绩查询梧州市一中学,梧州高中学校实力排名,2021年梧州所有的高中分数线排名...
  9. const指针 与指向const的指针的区别
  10. 转贴一个:中国股市,现在已经过了72小时最佳救援时间了!