Java根據(jù)code獲取枚舉優(yōu)化方式
需求
自己模擬兩個(gè)枚舉,假設(shè)業(yè)務(wù)中需要用到
Example1StatusEnum.java
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public enum Example1StatusEnum {
NEW("new", "新建狀態(tài)"),
FAIL("fail", "失敗狀態(tài)"),
SUCCESS("success", "成功狀態(tài)"),
CLOSED("closed", "關(guān)閉狀態(tài)");
private String code;
private String description;
Example1StatusEnum(String code, String description) {
this.code = code;
this.description = description;
}
}
Example2StatusEnum .java
package com.zdh.zdhenum;
import com.fasterxml.jackson.databind.ser.Serializers;
/**
* @author dh
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public enum Example2StatusEnum implements BaseEnum {
NEW("new", "新建狀態(tài)"),
FAIL("fail", "失敗狀態(tài)"),
SUCCESS("success", "成功狀態(tài)"),
PROCESSING("processing", "處理中狀態(tài)"),
WAITING("waiting", "等待狀態(tài)"),
CLOSED("closed", "關(guān)閉狀態(tài)"),
ABANDONED("abandoned", "棄狀態(tài)");
private String code;
private String description;
Example2StatusEnum(String code, String description) {
this.code = code;
this.description = description;
}
}
實(shí)際場景中,可能遠(yuǎn)遠(yuǎn)大于2個(gè),每個(gè)枚舉類內(nèi)item有唯一的code,實(shí)際業(yè)務(wù)開發(fā)中需要根據(jù)唯一的code獲取對(duì)應(yīng)的枚舉類型。
原始解決方案
哪個(gè)枚舉類需要根據(jù)code獲取對(duì)應(yīng)的枚舉,就在該枚舉類中添加獲取方法
例如Example1StatusEnum 需要根據(jù)code獲取對(duì)應(yīng)的枚舉,在Example1StatusEnum 添加如下方法:
public static Example1StatusEnum toEnum(String code){
for (Example1StatusEnum item : Example1StatusEnum.values()) {
if (Objects.equals(item.getCode(),code)) {
return item;
}
}
return null;
}
同理,其他需要用到此方法,都需要復(fù)制上面的方法,并更改為對(duì)應(yīng)類型,大量重復(fù)性工作。
優(yōu)化方案
1. 首先創(chuàng)建base接口。
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/23
* @desc (詳細(xì)信息)
*/
public interface BaseEnum {
/**
* 獲取code
* @return
*/
String getCode();
}
后面工具類根據(jù)此接口方法可以 通用的獲取code
2. 創(chuàng)建枚舉工具類
package com.zdh.zdhenum;
import java.util.Objects;
/**
* @author dh
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public class MyEnumUtil {
public static <E extends Enum<E> & BaseEnum> E toEnumByCode(String code, Class<E> enumClass) {
for (E enumConstant : enumClass.getEnumConstants()) {
if (Objects.equals(enumConstant.getCode(),code)) {
return enumConstant;
}
}
return null;
}
}
<E extends Enum<E> & BaseEnum> 這里泛型,extends 表現(xiàn)必須繼承自后面的xxx,BaseEnum規(guī)定必須實(shí)現(xiàn)上面定義的BaseEnum接口,Enum<E> 為枚舉類的公共父類,規(guī)定必須是枚舉類可以用此方法。
3. 需要使用工具類的枚舉,實(shí)現(xiàn)BaseEnum接口即可
例如,Example1StatusEnum 和Example2StatusEnum都需要使用。
分別修改如下:
package com.zdh.zdhenum;
import java.util.Objects;
/**
* @author dh
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public enum Example1StatusEnum implements BaseEnum{
NEW("new", "新建狀態(tài)"),
FAIL("fail", "失敗狀態(tài)"),
SUCCESS("success", "成功狀態(tài)"),
CLOSED("closed", "關(guān)閉狀態(tài)");
private String code;
private String description;
Example1StatusEnum(String code, String description) {
this.code = code;
this.description = description;
}
/**
* 獲取code
*
* @return
*/
@Override
public String getCode() {
return this.code;
}
}
package com.zdh.zdhenum;
import com.fasterxml.jackson.databind.ser.Serializers;
/**
* @author dh
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public enum Example2StatusEnum implements BaseEnum {
NEW("new", "新建狀態(tài)"),
FAIL("fail", "失敗狀態(tài)"),
SUCCESS("success", "成功狀態(tài)"),
PROCESSING("processing", "處理中狀態(tài)"),
WAITING("waiting", "等待狀態(tài)"),
CLOSED("closed", "關(guān)閉狀態(tài)"),
ABANDONED("abandoned", "棄狀態(tài)");
private String code;
private String description;
Example2StatusEnum(String code, String description) {
this.code = code;
this.description = description;
}
/**
* 獲取code
*
* @return
*/
@Override
public String getCode() {
return this.code;
}
}
4. 測試使用
public static void main(String[] args) {
Example1StatusEnum quotaStatusEnum11 = MyEnumUtil.toEnumByCode("new", Example1StatusEnum.class);
System.out.println("quotaStatusEnum11 = " + quotaStatusEnum11);
Example1StatusEnum quotaStatusEnum12 = MyEnumUtil.toEnumByCode("fda", Example1StatusEnum.class);
System.out.println("quotaStatusEnum12 = " + quotaStatusEnum12);
Example2StatusEnum quotaStatusEnum21 = MyEnumUtil.toEnumByCode("new", Example2StatusEnum.class);
System.out.println("quotaStatusEnum11 = " + quotaStatusEnum21);
Example2StatusEnum quotaStatusEnum22 = MyEnumUtil.toEnumByCode("fda", Example2StatusEnum.class);
System.out.println("quotaStatusEnum12 = " + quotaStatusEnum22);
}
為了方便查看效果,可以在最后打個(gè)斷點(diǎn)。

查看結(jié)果,發(fā)現(xiàn)和預(yù)期一樣

拓展
假設(shè),可能需要根據(jù)description 獲取枚舉,實(shí)際場景可能遇不到,重點(diǎn)在于思想。
那么幾種解決方案:
- 在原有的BaseEnum接口上加一個(gè)String getDescription(),然后MyEnumUtil 中添加一個(gè)和toEnumByCode類似的方法,泛型中依然使用BaseEnum。
- 新建一個(gè)新接口BaseDescEnum,里面就一個(gè)String getDescription()方法。然后MyEnumUtil 中添加一個(gè)和toEnumByCode類似的方法,泛型中使用新的BaseDescEnum。
這里我建議使用第2種方法,這樣顆粒度更細(xì)。第1種就算不需要根據(jù)description 獲取枚舉,也要實(shí)現(xiàn)String getDescription方法(雖然1.8之后可以通default關(guān)鍵字在接口默認(rèn)實(shí)現(xiàn),但是個(gè)人不太建議此場景這么使用)。
下面簡單說一下實(shí)現(xiàn)。
新增BaseDescEnum接口
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/23
* @desc (詳細(xì)信息)
*/
public interface BaseDescEnum {
/**
* 獲取description
* @return
*/
String getDescription();
}
假設(shè)僅僅Example1StatusEnum需要,代碼修改如下:
package com.zdh.zdhenum;
import java.util.Objects;
/**
* @author developer_ZhangXinHua
* @date 2024/07/24
* @desc (詳細(xì)信息)
*/
public enum Example1StatusEnum implements BaseEnum,BaseDescEnum{
NEW("new", "新建狀態(tài)"),
FAIL("fail", "失敗狀態(tài)"),
SUCCESS("success", "成功狀態(tài)"),
CLOSED("closed", "關(guān)閉狀態(tài)");
private String code;
private String description;
Example1StatusEnum(String code, String description) {
this.code = code;
this.description = description;
}
/**
* 獲取code
*
* @return
*/
@Override
public String getCode() {
return this.code;
}
/**
* 獲取description
*
* @return
*/
@Override
public String getDescription() {
return this.description;
}
}
MyEnumUtil中添加如下方法
public static <E extends Enum<E> & BaseDescEnum> E toEnumByDesc(String desc, Class<E> enumClass) {
for (E enumConstant : enumClass.getEnumConstants()) {
if (Objects.equals(enumConstant.getDescription(),code)) {
return enumConstant;
}
}
return null;
}
調(diào)用
public static void main(String[] args) {
Example1StatusEnum quotaStatusEnum11 = MyEnumUtil.toEnumByCode("new", Example1StatusEnum.class);
System.out.println("quotaStatusEnum11 = " + quotaStatusEnum11);
Example1StatusEnum quotaStatusEnum12 = MyEnumUtil.toEnumByCode("processing", Example1StatusEnum.class);
System.out.println("quotaStatusEnum12 = " + quotaStatusEnum12);
Example2StatusEnum quotaStatusEnum21 = MyEnumUtil.toEnumByCode("processing", Example2StatusEnum.class);
System.out.println("quotaStatusEnum11 = " + quotaStatusEnum21);
Example2StatusEnum quotaStatusEnum22 = MyEnumUtil.toEnumByCode("fda", Example2StatusEnum.class);
System.out.println("quotaStatusEnum12 = " + quotaStatusEnum22);
Example1StatusEnum enumByDesc11 = MyEnumUtil.toEnumByDesc("新建狀態(tài)", Example1StatusEnum.class);
System.out.println("enumByDesc11 = " + enumByDesc11);
Example1StatusEnum enumByDesc12 = MyEnumUtil.toEnumByDesc("xfdas", Example1StatusEnum.class);
System.out.println("enumByDesc12 = " + enumByDesc12);
// Example1StatusEnum enumByDesc13 = MyEnumUtil.toEnumByDesc("新建狀態(tài)", Example2StatusEnum.class);
// System.out.println("enumByDesc13 = " + enumByDesc13);
}
發(fā)現(xiàn)如果Example2StatusEnum沒有實(shí)現(xiàn)BaseDescEnum,連編譯都不能通過。為什么上文不建議使用default,這樣如果別人不熟悉實(shí)現(xiàn),使用我們的工具類,可以強(qiáng)制讓使用該工具類的人員,必須通過BaseDescEnum實(shí)現(xiàn)進(jìn)行重寫getDescription,防止忘記重寫getDescription,從而獲取到錯(cuò)誤的description。

正常獲取。

至此,優(yōu)化完成。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java面向?qū)ο蟪绦蛟O(shè)計(jì)多態(tài)性示例
這篇文章主要介紹了Java面向?qū)ο蟪绦蛟O(shè)計(jì)多態(tài)性,結(jié)合實(shí)例形式分析了java多態(tài)性的概念、原理、定義與使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-03-03
Spring中的@ExceptionHandler注解統(tǒng)一異常處理詳解
這篇文章主要介紹了Spring中的@ExceptionHandler注解統(tǒng)一異常處理詳解,當(dāng)我們使用這個(gè)@ExceptionHandler注解時(shí),定義一個(gè)異常的處理方法,加上@ExceptionHandler注解,這個(gè)方法就會(huì)處理類中其他方法拋出的異常,需要的朋友可以參考下2024-01-01
Java編程實(shí)現(xiàn)深度優(yōu)先遍歷與連通分量代碼示例
這篇文章主要介紹了Java編程實(shí)現(xiàn)深度優(yōu)先遍歷與連通分量代碼示例,2017-11-11
java.lang.UnsupportedOperationException分析及解決辦法
日常開發(fā)中我遇到j(luò)ava.lang.UnsupportedOperationException:異常兩次了,下面這篇文章主要給對(duì)大家介紹了關(guān)于java.lang.UnsupportedOperationException分析及解決辦法,需要的朋友可以參考下2024-03-03
SpringBoot集成easy-rules規(guī)則引擎流程詳解
這篇文章主要介紹了SpringBoot集成easy-rules規(guī)則引擎流程,合理的使用規(guī)則引擎可以極大的減少代碼復(fù)雜度,提升代碼可維護(hù)性。業(yè)界知名的開源規(guī)則引擎有Drools,功能豐富,但也比較龐大2023-03-03
Mybatis-plus動(dòng)態(tài)條件查詢QueryWrapper的使用案例
mybatis-plus框架功能很強(qiáng)大,把很多功能都集成了,下面這篇文章主要給大家介紹了關(guān)于Mybatis-plus動(dòng)態(tài)條件查詢QueryWrapper的使用教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
springBoot整合CXF并實(shí)現(xiàn)用戶名密碼校驗(yàn)的方法
這篇文章主要介紹了springBoot整合CXF并實(shí)現(xiàn)用戶名密碼校驗(yàn)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08

