万能的枚举类
不用枚举的时候如何写代码的
枚举可以定义一些固定的值,并且可以基于语法级别的校验代码的正确性。
例如:定义1正常 0不正常
如果我们代码写死,那么未来扩展或者修改了这个值,将是灾难性的,因为到处的代码都是类似下边这样的写法。特别是大型项目分布式项目下问题更加严重。
if(status == 1){
// .....
}
使用枚举解决问题
如果在代码中定义枚举
@Getter
@AllArgsConstructor
public enum CouponStatus {
NORMARL(1, "正常"),
NOT_NORMARL(0, "不正常");
private Integer code;
private String name;
}
那么我们的判断代码将这样写, 未来这个正常值改了,我需要改变枚举类即可,并且枚举名称的修改可以利用开发工具的引用分析同步修改所有的代码,非常的好用。
if(status == CouponStatus.NORMARL.getCode()){
// .....
}
范围判断
前端发起一个请求包含的status,前端传递的status值可以是1,0,2d都行,但是对于后端的接口收到了2并不是我们预先定义的值,在控制层就需要对值的范围进行校验,常规的写法:
@ApiOperation(value = "修改状态")
@PutMapping("/status")
public R<String> status(@RequestBody CoursePlanStatusDTO dto){
if (!ArrayUtil.contains(new int[]{1,0}, dto.getStatus())) {
return R.failed("状态不支持");
}
return xxxService.updateStatus(dto);
}
枚举值发生变化的时候,你需要到处搜索有使用到枚举值的地方,但是这些使用的地方貌似很多,苦不堪言。
新的解决思路—-使用枚举
@ApiOperation(value = "修改状态")
@PutMapping("/status")
public R<String> status(@RequestBody CoursePlanStatusDTO dto){
if (!ArrayUtil.contains(CouponStatus.ARRAY, dto.getStatus())) {
return R.failed("状态不支持");
}
return xxxService.updateStatus(dto);
}
CouponStatus.ARRAY
这个属性是怎么来的呢?谜底在最后
回显数据场景
当我们SQL查询的数据状态、类型字段的时候,可能你会在SQL中写一堆case When ,而这些代码没有类型检查的,写错了很可能就会有bug出现。具体的写法如下:
case when a.type == 1 then "正常"
when a.type == 0 then "不正常"
end
这种我更加倾向于在代码层面去处理这些枚举值,自带的java语法检测。
分页数据查询出来一个stream.foreach遍历数据,处理转换数据。
如果更加高效的去转换呢?
接下来将推出牛逼枚举的toMap、toArray的骚操作。。。
枚举工具类
这个工具能够帮助我们快速的将枚举类转换为map结构和数组结构,map结构可以很方便的根据key查询数据,数组结构可以很快速的判断wherein。
package com.jiayu.yoga.common.core.util;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* 枚举工具类
*
*
* @author marker
*/
public class EnumUtil {
/**
* 枚举转Map
* 方面转换数据
* @param enumClass 枚举类
* @param kMapper map k
* @param vMapper map v
* @param <E>
* @return
*/
public static <HK,HV,E> Map<HK, HV> toMap(Class<E> enumClass,
Function<? super E, ? extends HK > kMapper, Function<? super E, HV> vMapper){
Enum[] var2 = (Enum[]) enumClass.getEnumConstants();
int var3 = var2.length;
Map<HK, HV> map = new HashMap<>(var3);
for(int var4 = 0; var4 < var3; ++var4) {
E e = (E) var2[var4];
map.put( kMapper.apply(e), vMapper.apply(e));
}
return map;
}
/**
* 枚举转数组
* 应用场景:在接口参数校验时
* @param enumClass 枚举类
* @param kMapper 取数回调
* @param <V> 值
* @param <E> 类型
* @return
*/
public static <V, E> V[] toArray(Class<E> enumClass, Function<? super E, ? extends V > kMapper) {
Enum[] var2 = (Enum[]) enumClass.getEnumConstants();
int var3 = var2.length;
V[] array = null;
for (int var4 = 0; var4 < var3; ++var4) {
E e = (E) var2[var4];
V v = kMapper.apply(e);
if (var4 == 0) {
array = (V[]) Array.newInstance(v.getClass(), var3);
}
array[var4] = v;
}
return array;
}
public static <HK,E> E getEnumByKey(Class<E> enumClass,
Function<? super E, ? extends HK > kMapper, HK key){
Enum[] var2 = (Enum[]) enumClass.getEnumConstants();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
E e = (E) var2[var4];
if(kMapper.apply(e).equals(key)){
return e;
}
}
return null;
}
}
使用枚举工具类
缓存思想,将这些固定值缓存在数组或map中在不同的场景下使用。
@Getter
@AllArgsConstructor
public enum CouponStatus {
NORMARL(1, "正常"),
NOT_NORMARL(0, "不正常");
private Integer code;
private String name;
/**
* 枚举数据map化处理,为便于获取枚举数据.
*/
public static final Map<Integer, String> MAP = EnumUtil
.toMap(CouponStatus.class, CouponStatus::getCode, CouponStatus::getName);
/**
* 枚举数据array化处理,为便于获取枚举数据.
*/
public static final Integer[] ARRAY = EnumUtil.toArray(CouponStatus.class, CouponStatus::getCode);
}