枚举的本质
枚举类继承了Enum,并构造了枚举成员对象(静态final成员变量)
public final class Fruit extends Enum{
public static Fruit[] values()
{
return (Fruit[])$VALUES.clone();
}
public static Fruit valueOf(String s)
{
return (Fruit)Enum.valueOf(Fruit, s);
}
private Fruit(String s, int i, int j)
{
super(s, i);
code = j;
}
public static final Fruit APPLE;
public static final Fruit ORANGE;
public static final Fruit BANANA;
int code;
private static final Fruit $VALUES[];
static
{
APPLE = new Fruit("APPLE", 0, 1);
ORANGE = new Fruit("ORANGE", 1, 2);
BANANA = new Fruit("BANANA", 2, 3);
$VALUES = (new Fruit[] {
APPLE, ORANGE, BANANA
});
}}
-
获取枚举值工具类
```java public class EnumUtils {
private static final Map
private static final Set
enumSet = ConcurrentHashMap.newKeySet();
/**
* 带缓存的获取枚举值方式
*
* @param enumType 枚举类型
* @param keyFunction 根据枚举类型获取key的函数
* @param key 带匹配的Key
* @param <T> 枚举泛型
* @return 枚举类型
*/
public static <T extends java.lang.Enum<T>> Optional<T> getEnumWithCache(Class<T> enumType, Function<T, Object> keyFunction, Object key) {
if (!enumSet.contains(enumType)) {
// 不同的枚举类型相互不影响
synchronized (enumType) {
if (!enumSet.contains(enumType)) {
// 添加枚举
enumSet.add(enumType);
// 缓存枚举键值对
for (T enumThis : enumType.getEnumConstants()) {
// 避免重复
String mapKey = getKey(enumType, keyFunction.apply(enumThis));
key2EnumMap.put(mapKey, enumThis);
}
}
}
}
return Optional.ofNullable((T) key2EnumMap.get(getKey(enumType, key)));
}
/**
* 获取key
* 注:带上枚举路径避免不同枚举的Key 重复
*/
public static <T extends java.lang.Enum<T>> String getKey(Class<T> enumType, Object key) {
return enumType.getName().concat(key.toString());
}
/**
* 不带缓存的获取枚举值方式
*
* @param enumType 枚举类型
* @param keyFunction 根据枚举类型获取key的函数
* @param key 带匹配的Key
* @param <T> 枚举泛型
* @return 枚举类型
*/
public static <T extends java.lang.Enum<T>> Optional<T> getEnum(Class<T> enumType, Function<T, Object> keyFunction, Object key) {
for (T enumThis : enumType.getEnumConstants()) {
if (keyFunction.apply(enumThis).equals(key)) {
return Optional.of(enumThis);
}
}
return Optional.empty();
}
}
使用:
```java
@Test
public void test() {
int key = 5;
CoinEnum targetEnum = CoinEnum.NICKEL;
CoinEnum anEnum = CoinEnum.getEnum(key);
Assert.assertEquals(targetEnum, anEnum);
// 使用缓存
Optional<CoinEnum> enumWithCache = EnumUtils.getEnumWithCache(CoinEnum.class, CoinEnum::getValue, key);
Assert.assertTrue(enumWithCache.isPresent());
Assert.assertEquals(targetEnum, enumWithCache.get());
// 不使用缓存(遍历)
Optional<CoinEnum> enumResult = EnumUtils.getEnum(CoinEnum.class, CoinEnum::getValue, key);
Assert.assertTrue(enumResult.isPresent());
Assert.assertEquals(targetEnum, enumResult.get());
}