在我们的日常的开发中,枚举是无处不在的。比如我们使用到的各种状态各种类型都是需要使用枚举。也经常需要对枚举进行操作,例如 根据将 枚举的Value -> Name的操作(将枚举值转换为枚举的名称)。然而在我们的类中如果存在大量的枚举类,那么我们会乐此不疲的进行Ctrl +C -> Ctrl +V的操作。

    1. @Getter
    2. public enum EnumSubSceneType {
    3. /**
    4. * 逐业务改造
    5. */
    6. SERVICE("SERVICE"),
    7. /**
    8. * SRv6场景
    9. */
    10. SRV6("SRv6"),
    11. /**
    12. * IPv6场景
    13. */
    14. IPV6("IPv6");
    15. private String value;
    16. EnumSubSceneType(String value) {
    17. this.value = value;
    18. }
    19. /**
    20. * 根据子场景字符串获取子场景枚举
    21. *
    22. * @param subScene 子场景
    23. * @return 步骤名称
    24. */
    25. public static EnumSubSceneType getStepNameByNum(String subScene) {
    26. EnumSubSceneType[] enumTypes = values();
    27. for (EnumSubSceneType subTaskEnum : enumTypes) {
    28. if (subTaskEnum.getValue().equals(subScene)) {
    29. return subTaskEnum;
    30. }
    31. }
    32. return null;
    33. }
    34. /**
    35. * 获取枚举中的所有值
    36. *
    37. * @return 枚举中的所有值
    38. */
    39. public static List<String> getAllSubTaskType() {
    40. List<String> res = new ArrayList<>();
    41. EnumSubSceneType[] enumTypes = values();
    42. for (EnumSubSceneType subTaskEnum : enumTypes) {
    43. String s = subTaskEnum.getValue().toLowerCase(Locale.ENGLISH);
    44. res.add(s);
    45. }
    46. return res;
    47. }
    48. }

    那么我们是否有更好的方式来解决这一类的问题呢?做到代码的复用性搞,可扩展性强的优点呢?当然,Java是面向对象(面向接口编程)代码的复用性自然可以使用接口进行代替

    1. /**
    2. * 功能描述 简单的枚举类,即只包含value(实现此接口可使用{@link EnumUtils}中的方法
    3. *
    4. * @author h00518386
    5. * @since 2022-02-28
    6. */
    7. public interface ValueEnum<T> {
    8. /**
    9. * 获取枚举值
    10. *
    11. * @return 枚举值
    12. */
    13. T getValue();
    14. }

    扩展 ValueEnum 类。使得实现的枚举中即可拥有Name,也可以拥有Value

    1. /**
    2. * 功能描述:带有枚举Name和Value的接口(实现此接口可使用{@link EnumUtils}中的方法
    3. *
    4. * @author h00518386
    5. * @since 2022-02-28
    6. */
    7. public interface NameValueEnum<T> extends ValueEnum<T> {
    8. /**
    9. * 获取枚举名称
    10. * @return 枚举名
    11. */
    12. String getName();
    13. }

    把公共的代码进行抽取,使用泛型进行实现

    1. /*
    2. * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
    3. */
    4. package com.huawei.enumdemo;
    5. /**
    6. * 功能描述
    7. *
    8. * @author h00518386
    9. * @since 2022-02-28
    10. */
    11. import org.springframework.util.StringUtils;
    12. /**
    13. * 枚举常用工具类。<br/>
    14. * 使用该枚举工具类需要指定的枚举实现{@link ValueEnum} OR {@link NameValueEnum}接口
    15. *
    16. * @author meilin.huang
    17. * @version 1.0
    18. * @date 2019-03-22 11:12 AM
    19. */
    20. public final class EnumUtils {
    21. /**
    22. * 判断枚举值是否存在于指定枚举数组中
    23. *
    24. * @param enums 枚举数组
    25. * @param value 枚举值
    26. * @return 是否存在
    27. */
    28. public static <T> boolean isExist(ValueEnum<T>[] enums, T value) {
    29. if (value == null) {
    30. return false;
    31. }
    32. for (ValueEnum<T> e : enums) {
    33. if (value.equals(e.getValue())) {
    34. return true;
    35. }
    36. }
    37. return false;
    38. }
    39. /**
    40. * 判断枚举值是否存与指定枚举类中
    41. *
    42. * @param enumClass 枚举类
    43. * @param value 枚举值
    44. * @param <E> 枚举类型
    45. * @param <V> 值类型
    46. * @return true:存在
    47. */
    48. @SuppressWarnings("unchecked")
    49. public static <E extends Enum<? extends ValueEnum<V>>, V> boolean isExist(Class<E> enumClass, V value) {
    50. for (Enum<? extends ValueEnum<V>> e : enumClass.getEnumConstants()) {
    51. if (((ValueEnum<V>) e).getValue().equals(value)) {
    52. return true;
    53. }
    54. }
    55. return false;
    56. }
    57. /**
    58. * 根据枚举值获取其对应的名字
    59. *
    60. * @param enums 枚举列表
    61. * @param value 枚举值
    62. * @return 枚举名称
    63. */
    64. public static <T> String getNameByValue(NameValueEnum<T>[] enums, T value) {
    65. if (value == null) {
    66. return null;
    67. }
    68. for (NameValueEnum<T> e : enums) {
    69. if (value.equals(e.getValue())) {
    70. return e.getName();
    71. }
    72. }
    73. return null;
    74. }
    75. /**
    76. * 根据枚举名称获取对应的枚举值
    77. *
    78. * @param enums 枚举列表
    79. * @param name 枚举名
    80. * @return 枚举值
    81. */
    82. public static <T> T getValueByName(NameValueEnum<T>[] enums, String name) {
    83. if (StringUtils.isEmpty(name)) {
    84. return null;
    85. }
    86. for (NameValueEnum<T> e : enums) {
    87. if (name.equals(e.getName())) {
    88. return e.getValue();
    89. }
    90. }
    91. return null;
    92. }
    93. /**
    94. * 根据枚举值获取对应的枚举对象
    95. *
    96. * @param enums 枚举列表
    97. * @return 枚举对象
    98. */
    99. @SuppressWarnings("unchecked")
    100. public static <E extends Enum<? extends ValueEnum<V>>, V> E getEnumByValue(E[] enums, V value) {
    101. for (E e : enums) {
    102. if (((ValueEnum<V>) e).getValue().equals(value)) {
    103. return e;
    104. }
    105. }
    106. return null;
    107. }
    108. /**
    109. * 根据枚举值获取对应的枚举对象
    110. *
    111. * @param enumClass 枚举class
    112. * @return 枚举对象
    113. */
    114. public static <E extends Enum<? extends ValueEnum<V>>, V> E getEnumByValue(Class<E> enumClass, V value) {
    115. return getEnumByValue(enumClass.getEnumConstants(), value);
    116. }
    117. }

    测试代码案例:

    1. /*
    2. * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
    3. */
    4. import org.junit.Assert;
    5. import org.junit.Test;
    6. /**
    7. * 功能描述
    8. *
    9. * @author h00518386
    10. * @since 2022-02-28
    11. */
    12. public class EnumUtilsTest {
    13. enum TestStrEnum implements NameValueEnum<String> {
    14. T1("01", "String类型测试1"),
    15. T2("02", "String类型测试2");
    16. private final String value;
    17. private final String name;
    18. TestStrEnum(String value, String name) {
    19. this.value = value;
    20. this.name = name;
    21. }
    22. @Override
    23. public String getName() {
    24. return this.name;
    25. }
    26. @Override
    27. public String getValue() {
    28. return this.value;
    29. }
    30. }
    31. enum TestIntEnum implements NameValueEnum<Integer> {
    32. T1(1, "Integer类型测试1"),
    33. T2(2, "Integer类型测试2");
    34. private final Integer value;
    35. private final String name;
    36. TestIntEnum(Integer value, String name) {
    37. this.value = value;
    38. this.name = name;
    39. }
    40. @Override
    41. public String getName() {
    42. return this.name;
    43. }
    44. @Override
    45. public Integer getValue() {
    46. return this.value;
    47. }
    48. }
    49. enum TestOnlyValueEnum implements ValueEnum<String> {
    50. T1("test1");
    51. private final String value;
    52. TestOnlyValueEnum(String value) {
    53. this.value = value;
    54. }
    55. @Override
    56. public String getValue() {
    57. return this.value;
    58. }
    59. }
    60. @Test
    61. public void isExist() {
    62. Assert.assertTrue(EnumUtils.isExist(TestStrEnum.values(), "01"));
    63. Assert.assertFalse(EnumUtils.isExist(TestStrEnum.values(), "03"));
    64. Assert.assertTrue(EnumUtils.isExist(TestIntEnum.values(), 2));
    65. Assert.assertFalse(EnumUtils.isExist(TestIntEnum.values(), 8));
    66. }
    67. @Test
    68. public void getNameByValue() {
    69. String name = EnumUtils.getNameByValue(TestStrEnum.values(), "01");
    70. String name2 = EnumUtils.getNameByValue(TestIntEnum.values(), 2);
    71. System.out.println(name);
    72. System.out.println(name2);
    73. }
    74. @Test
    75. public void getValueByName() {
    76. String value = EnumUtils.getValueByName(TestStrEnum.values(), "String类型测试1");
    77. Integer value2 = EnumUtils.getValueByName(TestIntEnum.values(), "Integer类型测试2");
    78. System.out.println(value);
    79. System.out.println(value2);
    80. }
    81. @Test
    82. public void getEnumByValue() {
    83. TestIntEnum enumByValue = EnumUtils.getEnumByValue(TestIntEnum.values(), 1);
    84. TestStrEnum test = EnumUtils.getEnumByValue(TestStrEnum.class, "02");
    85. }
    86. }