枚举的本质

枚举类继承了Enum,并构造了枚举成员对象(静态final成员变量)

  1. public final class Fruit extends Enum{
  2. public static Fruit[] values()
  3. {
  4. return (Fruit[])$VALUES.clone();
  5. }
  6. public static Fruit valueOf(String s)
  7. {
  8. return (Fruit)Enum.valueOf(Fruit, s);
  9. }
  10. private Fruit(String s, int i, int j)
  11. {
  12. super(s, i);
  13. code = j;
  14. }
  15. public static final Fruit APPLE;
  16. public static final Fruit ORANGE;
  17. public static final Fruit BANANA;
  18. int code;
  19. private static final Fruit $VALUES[];
  20. static
  21. {
  22. APPLE = new Fruit("APPLE", 0, 1);
  23. ORANGE = new Fruit("ORANGE", 1, 2);
  24. BANANA = new Fruit("BANANA", 2, 3);
  25. $VALUES = (new Fruit[] {
  26. APPLE, ORANGE, BANANA
  27. });
  28. }}
  • valueOf用来根据枚举获取常量。

    获取枚举值工具类

    ```java public class EnumUtils {

    private static final Map key2EnumMap = new ConcurrentHashMap<>();

    private static final Set enumSet = ConcurrentHashMap.newKeySet();

  1. /**
  2. * 带缓存的获取枚举值方式
  3. *
  4. * @param enumType 枚举类型
  5. * @param keyFunction 根据枚举类型获取key的函数
  6. * @param key 带匹配的Key
  7. * @param <T> 枚举泛型
  8. * @return 枚举类型
  9. */
  10. public static <T extends java.lang.Enum<T>> Optional<T> getEnumWithCache(Class<T> enumType, Function<T, Object> keyFunction, Object key) {
  11. if (!enumSet.contains(enumType)) {
  12. // 不同的枚举类型相互不影响
  13. synchronized (enumType) {
  14. if (!enumSet.contains(enumType)) {
  15. // 添加枚举
  16. enumSet.add(enumType);
  17. // 缓存枚举键值对
  18. for (T enumThis : enumType.getEnumConstants()) {
  19. // 避免重复
  20. String mapKey = getKey(enumType, keyFunction.apply(enumThis));
  21. key2EnumMap.put(mapKey, enumThis);
  22. }
  23. }
  24. }
  25. }
  26. return Optional.ofNullable((T) key2EnumMap.get(getKey(enumType, key)));
  27. }
  28. /**
  29. * 获取key
  30. * 注:带上枚举路径避免不同枚举的Key 重复
  31. */
  32. public static <T extends java.lang.Enum<T>> String getKey(Class<T> enumType, Object key) {
  33. return enumType.getName().concat(key.toString());
  34. }
  35. /**
  36. * 不带缓存的获取枚举值方式
  37. *
  38. * @param enumType 枚举类型
  39. * @param keyFunction 根据枚举类型获取key的函数
  40. * @param key 带匹配的Key
  41. * @param <T> 枚举泛型
  42. * @return 枚举类型
  43. */
  44. public static <T extends java.lang.Enum<T>> Optional<T> getEnum(Class<T> enumType, Function<T, Object> keyFunction, Object key) {
  45. for (T enumThis : enumType.getEnumConstants()) {
  46. if (keyFunction.apply(enumThis).equals(key)) {
  47. return Optional.of(enumThis);
  48. }
  49. }
  50. return Optional.empty();
  51. }

}

  1. 使用:
  2. ```java
  3. @Test
  4. public void test() {
  5. int key = 5;
  6. CoinEnum targetEnum = CoinEnum.NICKEL;
  7. CoinEnum anEnum = CoinEnum.getEnum(key);
  8. Assert.assertEquals(targetEnum, anEnum);
  9. // 使用缓存
  10. Optional<CoinEnum> enumWithCache = EnumUtils.getEnumWithCache(CoinEnum.class, CoinEnum::getValue, key);
  11. Assert.assertTrue(enumWithCache.isPresent());
  12. Assert.assertEquals(targetEnum, enumWithCache.get());
  13. // 不使用缓存(遍历)
  14. Optional<CoinEnum> enumResult = EnumUtils.getEnum(CoinEnum.class, CoinEnum::getValue, key);
  15. Assert.assertTrue(enumResult.isPresent());
  16. Assert.assertEquals(targetEnum, enumResult.get());
  17. }