原创
优化if-else之Java枚举中的两个小技巧
温馨提示:
本文最后更新于 2020年11月16日,已超过 1,467 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
还是按常规操作走一波
什么是枚举?
枚举类型是Java 5中新增特性的一部分,它是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。
大部分人如何使用枚举?
e.g.大部分人都是直接就时一想到枚举,昂,我常量写在枚举中/静态常量。
public enum MenuType {
CATEGORY,
PAGE,
BUTTON
}
1.枚举中的比对值
昂,这个名称我乱起的,哈哈哈,Because match
,听到比对我就马上能够想到match
,仅此而已,怎么舒服怎么来。
我们只需要传入WindingPolarizationTaskEnum
的value,然后使用match
方法,就可以返回我们需要的枚举类型了。
public enum WindingPolarizationTaskEnum {
HIGH_LOW_WITH_GROUND(0, "高压-低压及地"),
LOW_HIGH_WITH_GROUND(1, "低压-高压及地"),
HIGH_LOW_GROUND(2, "高压、低压-地"),
OTHER(3, "其它试验数据");
WindingPolarizationTaskEnum(Integer number, String desc) {
this.number = number;
this.desc = desc;
}
private Integer number;
private String desc;
/**
* 根据类型返回具体的WindingPolarizationTaskEnum
*
* @param number number
* @return WindingPolarizationTaskEnum
*/
public static WindingPolarizationTaskEnum match(Integer number) {
for (WindingPolarizationTaskEnum item : WindingPolarizationTaskEnum.values()) {
if (item.number.equals(number)) {
return item;
}
}
return WindingPolarizationTaskEnum.HIGH_LOW_WITH_GROUND;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
2.其实枚举类型中是可以定义方法的
demo1
来看一下我在学校时期写的一段代码…注释上都有,就不重复解释了。
import com.data.DataService;
import com.model.msgtype.opendevicealarmtype.OpenDeviceAlarm;
import com.model.msgtype.opendeviceonofflinetype.OpenDeviceOnoffline;
import com.model.msgtype.openeventaccessbatchdeliveredtype.OpenEventAccessBatchDelivered;
import com.model.msgtype.openeventaccesstype.OpenEventAccess;
import com.model.msgtype.openeventsuperbrainfacesdeliveredtype.OpenEventSuperBrainFacesDelivered;
import com.model.msgtype.openezvizdetectoralarmtype.OpenEzvizDetectorAlarm;
import com.model.msgtype.openfacecapturetype.OpenFaceCapture;
import com.model.msgtype.openidcardeventtype.OpenIdcardEvent;
import com.model.msgtype.openmessageanpr.OpenMessageAnpr;
import com.model.msgtype.openmessagetma.OpenMessageTma;
import com.model.msgtype.openpassengerflowtype.OpenPassengerFlow;
import com.model.msgtype.openpersonqueuecountingtype.OpenPersonQueueCounting;
import com.response.ErrorCode;
import com.response.hkym.CommonObj;
import com.util.JsonUtil;
import java.io.IOException;
/**
* 消息类型
* <p>
* 我想到的优化(if-else、switch)的解决方案:
* 1. 使用容器,每个方法都换成一个类,但这样的话,就要多加很多个类
* 2. 使用反射,但是反射的速度太慢了。
* 3. 使用函数式接口,使用函数式接口作为容器的元素。
* 4. 用Runnable。
* 5. 设计模式(状态模式、策略模式、工厂模式)
* 6. 枚举 + 方法。
* </p>
* @author lzhpo
*/
public enum MsgTypeEnum {
/** 门禁事件消息 */
OPEN_EVENT_ACCESS("open_event_access") {
@Override
OpenEventAccess run(String content) throws IOException {
System.out.println("门禁事件消息:" +content);
return JsonUtil.parse(content, OpenEventAccess.class);
}
},
/** 人证比对事件 */
OPEN_IDCARD_EVENT("open_idcard_event") {
@Override
OpenIdcardEvent run(String content) throws IOException {
System.out.println("人证比对事件:" +content);
return JsonUtil.parse(content, OpenIdcardEvent.class);
}
},
/** 客流消息 */
OPEN_PASSENGERFLOW("open_passengerFlow") {
@Override
OpenPassengerFlow run(String content) throws IOException {
System.out.println("客流消息:" +content);
OpenPassengerFlow openPassengerFlow = JsonUtil.parse(content, OpenPassengerFlow.class);
DataService.leave += openPassengerFlow.getLeaveNum();
DataService.enter += openPassengerFlow.getEnterNum();
DataService.pass += openPassengerFlow.getLeaveNum() + openPassengerFlow.getEnterNum();
openPassengerFlow.setEnterNum(DataService.enter);
openPassengerFlow.setLeaveNum(DataService.leave);
openPassengerFlow.setPassNum(DataService.pass);
return openPassengerFlow;
}
},
/** 人脸抓拍消息 */
OPEN_FACE_CAPTURE("open_face_capture") {
@Override
OpenFaceCapture run(String content) throws IOException {
System.out.println("人脸抓拍消息:" +content);
return JsonUtil.parse(content, OpenFaceCapture.class);
}
},
/** 门禁批量下发消息 */
OPEN_EVENT_ACCESS_BATCH_DELIVERED("open_event_access_batch_delivered") {
@Override
OpenEventAccessBatchDelivered run(String content) throws IOException {
System.out.println("门禁批量下发消息:" +content);
return JsonUtil.parse(content, OpenEventAccessBatchDelivered.class);
}
},
/** 超脑人脸下发消息 */
OPEN_EVENT_SUPER_BRAIN_FACES_DELIVERED("open_event_super_brain_faces_delivered") {
@Override
OpenEventSuperBrainFacesDelivered run(String content) throws IOException {
System.out.println("超脑人脸下发消息:" +content);
return JsonUtil.parse(content, OpenEventSuperBrainFacesDelivered.class);
}
},
/** 超脑人脸比对消息 */
OPEN_EVENT_SUPER_BRAIN_FACES_COMPARISON("open_event_super_brain_faces_comparison") {
@Override
OpenEventSuperBrainFacesDelivered run(String content) throws IOException {
System.out.println("超脑人脸比对消息:" +content);
return JsonUtil.parse(content, OpenEventSuperBrainFacesDelivered.class);
}
},
/** 萤石探测器报警消息 */
OPEN_EZVIZ_DETECTOR_ALARM("open_ezviz_detector_alarm") {
@Override
OpenEzvizDetectorAlarm run(String content) throws IOException {
System.out.println("萤石探测器报警消息:" +content);
return JsonUtil.parse(content, OpenEzvizDetectorAlarm.class);
}
},
/** 设备报警消息 */
OPEN_DEVICE_ALARM("open_device_alarm") {
@Override
OpenDeviceAlarm run(String content) throws IOException {
System.out.println("设备报警消息:" +content);
return JsonUtil.parse(content, OpenDeviceAlarm.class);
}
},
/** 设备上下线消息 */
OPEN_DEVICE_ONOFFLINE("open_device_onoffline") {
@Override
OpenDeviceOnoffline run(String content) throws IOException {
System.out.println("设备上下线消息:" +content);
return JsonUtil.parse(content, OpenDeviceOnoffline.class);
}
},
/** 车辆抓拍消息 */
OPEN_MESSAGE_ANPR("open_message_anpr") {
@Override
OpenMessageAnpr run(String content) throws IOException {
System.out.println("车辆抓拍消息:" +content);
return JsonUtil.parse(content, OpenMessageAnpr.class);
}
},
/** 测温报警消息 */
OPEN_MESSAGE_TMA("open_message_tma") {
@Override
OpenMessageTma run(String content) throws IOException {
System.out.println("测温报警消息:" +content);
return JsonUtil.parse(content, OpenMessageTma.class);
}
},
/** 区域人数超限报警消息 */
OPEN_PERSON_QUEUE_COUNTING("open_person_queue_counting") {
@Override
OpenPersonQueueCounting run(String content) throws IOException {
System.out.println("区域人数超限报警消息:" +content);
return JsonUtil.parse(content, OpenPersonQueueCounting.class);
}
};
private String type;
MsgTypeEnum() {
}
MsgTypeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/** 定义枚举的方法 */
abstract <T> T run(String content) throws IOException;
/**
* 比对消息类型,然后执行run方法,返回对应的content值
*
* @param type 消息类型
* @param content 消息类型对应的内容
* @return map 消息类型和消息类型对应的content数据
*/
public static <T> CommonObj<T> matchTypeRun(String type, String content) throws IOException {
for (MsgTypeEnum item : MsgTypeEnum.values()) {
if (item.type.equals(type)) {
CommonObj<T> commonObj = new CommonObj<>();
commonObj.setCode(ErrorCode.SUCCESS.code);
commonObj.setSuccess(Boolean.TRUE);
// 设置消息类型
commonObj.setMessage(type);
// 设置消息数据
commonObj.setData(item.run(content));
return commonObj;
}
}
return new CommonObj<>(ErrorCode.FAIL.code, "获取消息数据失败", false);
}
}
使用:
CommonObj<Object> msgContentObj = MsgTypeEnum.matchTypeRun(consumeMsg.getMsgType(), consumeMsg.getContent());
在MsgTypeEnum
中,我定义了一个抽象枚举方法run
,在枚举类型中实现了run
方法。
这里主要是根据传入的数据类型进行不同的反序列化,然后再返回。
demo2
可能上面的有泛型,为了方便各位理解,我再来一个没有泛型的,帮助各位理解一下。
import com.withive.project.tools.file.entity.DebugCorrelationFile;
/**
* 文件关联的类型
*
* @author Zhaopo Liu
*/
public enum DbgFileType {
/**
* 设备参数
*/
DEVICE_PARAMS(0) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.deviceParamsId(correlationId)
.build();
}
},
/**
* 测量绕组连同套管的直流电阻
*/
WINDING_TASK(1) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.windingTaskId(correlationId)
.build();
}
},
/**
* 所有分接头的电压比及三相组别ID
*/
TAP_THREE_TEST_TASK(2) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.tapThreeTestTaskId(correlationId)
.build();
}
},
/**
* 绕组连同套管的绝缘电阻、吸收比或极化指数
*/
WINDING_POLARIZATION_TASK(3) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.windingPolarizationTaskId(correlationId)
.build();
}
},
/**
* 介质损耗及电容值测试
*/
MEDIUM_CAPACITANCE_LOSS(4) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.mediumCapacitanceLossId(correlationId)
.build();
}
},
/**
* 绕组连同套管的交流耐压试验
*/
WINDING_AC_TASK(5) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.windingAcTaskId(correlationId)
.build();
}
},
/**
* 与铁心绝缘的各紧固件及铁心的绝缘电阻
*/
IRON_FASTENERS_INSULATION_TASK(6) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.ironFastenersInsulationTaskId(correlationId)
.build();
}
},
/**
* 绕组变形(电抗法)
*/
WINDING_DEFORMATION_TASK(7) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.windingDeformationTaskId(correlationId)
.build();
}
},
/**
* 试验结论
*/
DEBUG_TASK(8) {
@Override
DebugCorrelationFile run(Long fileId, Long correlationId) {
return DebugCorrelationFile.builder()
.fileId(fileId)
.debugTaskId(correlationId)
.build();
}
};
private Integer type;
DbgFileType() {
}
DbgFileType(Integer type) {
this.type = type;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
/**
* 定义抽象方法
*/
abstract DebugCorrelationFile run(Long fileId, Long correlationId);
/**
* 比对消息类型,然后执行run方法,返回对应的DebugCorrelationFile{@link DebugCorrelationFile}
*
* @param dbgType 试验类型
* @param fileId 文件ID
* @param correlationId 哪个试验项目的ID
* @return DebugCorrelationFile
*/
public static DebugCorrelationFile matchTypeRun(Integer dbgType, Long fileId, Long correlationId) {
for (DbgFileType item : DbgFileType.values()) {
if (item.type.equals(dbgType)) {
return item.run(fileId, correlationId);
}
}
return null;
}
}
在DbgFileType
中,我写了一个抽象方法run
,它需要传入文件ID和实验项目的ID。
在matchTypeRun
中,我传入的参数就多了一个dbgType
,也就是DbgFileType
的枚举值,这里就将我前面说的match
方法,传入枚举值,返回枚举类型,枚举类型中实现了我定义的抽象方法run
,最终返回我需要的DebugCorrelationFile
。
使用demo:
DebugCorrelationFile debugCorrelationFile = DbgFileType.matchTypeRun(dbgFileTypeNum, entity.getId(), correlationId);
- 本文标签: Java
- 本文链接: http://www.lzhpo.com/article/161
- 版权声明: 本文由lzhpo原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权