分享两个操作Java枚举的实用方法
1. 前言
Java枚举在开发中是非常实用的。今天再来分析几个小技巧并且回答一些同学的的疑问。首先要说明的是我的枚举建立在以下的范式之中:
枚举统一接口范式
2. 如何把枚举值绑定的下拉列表
这种场景非常常见,如果你把状态、类别等属性封装成枚举的结构,就像下面一样,一个标识对应一个状态,这是典型的下拉列表结构。
public enum EnabledEnum implements Enumerator {
/**
* Disable status enum.
*/
DISABLE(0, "不可用"),
/**
* Enable status enum.
*/
ENABLE(1, "可用");
private final int value;
private final String description;
EnabledEnum(int value, String description) {
this.value = value;
this.description = description;
}
@Override
public int value() {
return this.value;
}
@Override
public String description() {
return this.description;
}
}
前端希望能够获取这些状态作为下拉列表的填充,你该如何解析封装它呢?这里我有两个办法,第一个你可以从JSON 类库 Jackson 优雅序列化 Java 枚举类一文获得解决方案;第二种更加简单一些,写一个工具类就可以了。
public static <E extends Enum<?> & Enumerator> Map<Integer, String> enumToMap(Class<E> clazz) {
E[] enumConstants = clazz.getEnumConstants();
Map<Integer, Object> map = new LinkedHashMap<>();
for (E e : enumConstants) {
map.put(e.value(), e.description());
}
return map;
}
这里用了Java 8的新特性附加约束。也就是说extends
后面可以在通过&
符号附加额外约束,可以重复使用,注意必须为接口类型,不能为抽象类或者其他Class
。表示泛型的上界受到多个约束的制约。<E extends Enum<?> & Enumerator>
可以解读为E
必须为一个枚举类而且同时还必须实现Enumerator
接口。
为什么实现
Enumerator
接口?第一个好处是可以规定统一的范式;第二个好处是解析的时候不用转换了。
此外我尝试用Stream
来封装,但是发现过于复杂了,虽然成功了但是有点难以理解,这里也分享一下:
public static <E extends Enum<?> & Enumerator> Map<Integer, String> enumToOptions(Class<E> enumClazz){
// 合并时检查 key 是否重复
BinaryOperator<String> merge = (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
};
Enumerator[] enumConstants = enumClazz.getEnumConstants();
return Stream.of(enumConstants)
.collect(Collectors.toMap(Enumerator::value,
Enumerator::description,
merge,LinkedHashMap::new));
}
3. 如何根据值找到枚举
这种也很常见,最直接的方式是写一个switch语句。但是每个类都写一个就非常繁琐。所以这个也可以写一个工具类,这次用Stream
就简单的多了。
public static <E extends Enum<?> & Enumerator> Optional<E> getEnumByValue(Class<E> enumClazz, final Integer value){
return Stream.of(enumClazz.getEnumConstants())
.filter(enumerator -> Objects.equals(enumerator.code(),value))
.findAny();
}
返回
Optional
是因为有可能给出的value
没有对应的枚举。
4. 总结
今天分享了两个小工具类来操作枚举,不光运用了枚举的一些知识,同时也使用了Java 8的三个新特性:泛型附加约束、Optional和Stream API。这些知识点以往我都分享过,有兴趣的可以到 felord.cn 搜索一下。如果你有更好的办法可以留言讨论。多多关注:码农小胖哥,更多原创干货分享。
- nyoj---快速查找素数
- 转--Golang图像处理工具库,图像相似度计算,图像二值化
- HDUOJ----湫湫系列故事——减肥记I
- HDUOJ----Eddy's research I
- 【亚马逊加盟对抗谷歌联盟ONNX】微软Facebook深度学习开源联盟再添盟友
- HDUOJ--8球胜负
- HDUOJ--点球大战
- Golang语言社区--使用百度API获取经纬度
- HDUOJ---The number of divisors(约数) about Humble Numbers
- HDUOJ----最少拦截系统
- Go语言截取字符串函数用法
- HDUOJ -----免费馅饼
- HDUOJ----Super Jumping! Jumping! Jumping!
- HDUOJ----数塔
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 蓝桥杯vip测试题系统-数组求和(解题思路以及解题代码,手画思路图虽然丑丑的)
- 蓝桥杯vip测试题-找零钱(解题思路以及解题代码)
- 剑指Office-二进制中1的个数
- 剑指Office-旋转数组的最小数
- Mysql调优你不知道这几点,就太可惜了
- Mysql快速导入数百万条数据,亲测有效
- [面试题06]从未到头打印链表(LeetCode-剑指Offer)
- SpringBoot集成RabbitMQ-三种模式的实现
- Centos7-Docker卸载旧的更新到新版本
- vue vuecli3 前端解决跨域问题
- 求求你,不要再纠结指针了(1) ——万能转化公式
- 求求你,不要再纠结指针了(2)——函数指针
- 用Python解决100个问题 | 倒计时
- 【转载】【ionic+angularjs】angularjs ui-router路由简介
- 实时性迷思(1) —— “快是优点么?”