【世一枚举】2025年了原来枚举还能这样用

217 阅读4分钟

短信枚举类

常规枚举定义,直接看下面

@AllArgsConstructor
@Getter
public enum ESmsSendType implements IEnum {

    A_LI_YUN(1, "阿里云", "ALI"),
    TENCENT_YUN(2, "腾讯云", "TX"),
    ZK_YUN(3, "直客云", "ZK"),
    CAT_YUN(4, "短信猫", "CAT"),
    ;

    private final Integer type;
    private final String desc;
    private final String strategyName;
}

上实战演示

以前我们获取枚举类型

当我们想要获取短信类型为1(阿里云)的枚举类,以前我们需要这样做

@Test
void contextLoads() {
    int aliType = 1;
    ESmsSendType instance = null;
    ESmsSendType[] values = ESmsSendType.values();
    for (int i = 0; i < values.length; i++) {
        if(values[i].getType() == aliType) {
            instance = values[i];
        }
    }
    // 判断两个枚举类是否相等
    System.out.println(instance == ESmsSendType.A_LI_YUN);
}

2025年我们获取枚举类型

现在我们只需要两行,看好了,看好了,不要眨眼 ~ 两行搞定!!!

@Test
void contextLoads() {
    int aliType = 1;
    ESmsSendType anEnum = IEnum.getEnum(aliType, ESmsSendType.class);
    // 判断两个枚举类是否相等
    System.out.println(IEnum.eq(anEnum, ESmsSendType.A_LI_YUN));
}

接口封装

陆总大佬封装的枚举接口 orrz,非常好用 orrz,强烈推荐!!!我愿称陆总为Java枚举界第一人。

package cn.bdmcom.enums;

import cn.hutool.core.util.ObjectUtil;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 通用枚举接口,提供统一的枚举操作工具方法。
 */
public interface IEnum {

    /**
     * 全局缓存,保存所有枚举类及其对应的枚举值。
     * Key:枚举类;Value:一个Map,其中Key为枚举类型值,Value为枚举实例。
     */
    Map<Class<?>, Map<Integer, Enum<?>>> enumCache = new ConcurrentHashMap<>();

    /**
     * 获取枚举的类型值。
     *
     * @return 枚举的类型值(Integer类型)。
     */
    Integer getType();

    /**
     * 获取枚举的描述。
     *
     * @return 枚举的描述(String类型)。
     */
    String getDesc();

    /**
     * 获取类型值的字符串形式。
     *
     * @return 类型值的字符串形式;如果类型值为null,则返回null。
     */
    default String getTypeString() {
        return getType() != null ? getType().toString() : null;
    }

    /**
     * 根据类型值获取枚举实例。
     *
     * @param type  枚举类型值(Integer)。
     * @param clazz 枚举类的Class对象。
     * @param <E>   泛型,必须是IDictEnum接口的实现类。
     * @return 对应类型值的枚举实例;如果找不到或参数无效,返回null。
     */
    static <E extends Enum<E> & IEnum> E getEnum(Integer type, Class<E> clazz) {
        if (type == null || clazz == null) {
            return null;
        }

        // 获取或初始化缓存
        Map<Integer, Enum<?>> integerEnumMap = enumCache.computeIfAbsent(clazz, k -> new ConcurrentHashMap<>());

        // 优先从缓存中获取
        Enum<?> anEnum = integerEnumMap.get(type);
        if (anEnum != null) {
            return clazz.cast(anEnum);
        }

        // 遍历枚举类中的所有实例并缓存
        EnumSet<E> enumSet = EnumSet.allOf(clazz);
        E result = enumSet.stream()
                .filter(e -> Objects.equals(e.getType(), type))
                .findFirst()
                .orElse(null);

        if (result != null) {
            integerEnumMap.put(type, result);
        }
        return result;
    }

    /**
     * 根据字符串类型值获取枚举实例。
     *
     * @param type  类型值(字符串形式)。
     * @param clazz 枚举类的Class对象。
     * @param <E>   泛型,必须是IDictEnum接口的实现类。
     * @return 对应类型值的枚举实例;如果类型值无效或找不到对应枚举,返回null。
     */
    static <E extends Enum<E> & IEnum> E getEnum(String type, Class<E> clazz) {
        if (type == null) {
            return null;
        }
        try {
            return getEnum(Integer.valueOf(type), clazz);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 获取枚举实例,如果不存在则返回默认值。
     *
     * @param type         枚举类型值。
     * @param clazz        枚举类的Class对象。
     * @param defaultValue 默认值。
     * @param <E>          泛型,必须是IDictEnum接口的实现类。
     * @return 对应类型值的枚举实例;如果找不到,则返回defaultValue。
     */
    static <E extends Enum<E> & IEnum> E defaultEnum(Integer type, Class<E> clazz, E defaultValue) {
        return ObjectUtil.defaultIfNull(getEnum(type, clazz), defaultValue);
    }

    /**
     * 根据描述获取枚举实例。
     *
     * @param desc  枚举描述。
     * @param clazz 枚举类的Class对象。
     * @param <E>   泛型,必须是IDictEnum接口的实现类。
     * @return 对应描述的枚举实例;如果找不到,返回null。
     */
    static <E extends Enum<E> & IEnum> E getEnumByDesc(String desc, Class<E> clazz) {
        if (desc == null || clazz == null) {
            return null;
        }

        return EnumSet.allOf(clazz)
                .stream()
                .filter(e -> Objects.equals(e.getDesc(), desc))
                .findFirst()
                .orElse(null);
    }

    /**
     * 根据类型值获取枚举描述。
     *
     * @param type  枚举类型值。
     * @param clazz 枚举类的Class对象。
     * @param <E>   泛型,必须是IDictEnum接口的实现类。
     * @return 对应类型值的描述;如果找不到,返回null。
     */
    static <E extends Enum<E> & IEnum> String getEnumByType(Integer type, Class<E> clazz) {
        E anEnum = getEnum(type, clazz);
        return anEnum != null ? anEnum.getDesc() : null;
    }

    /**
     * 判断两个枚举是否相等。
     *
     * @param e1 第一个枚举实例。
     * @param e2 第二个枚举实例。
     * @return 如果两个枚举的类型值和描述均相等,返回true;否则返回false。
     */
    static boolean eq(IEnum e1, IEnum e2) {
        if (e1 == e2) {
            return true;
        }
        if (e1 == null || e2 == null) {
            return false;
        }
        return Objects.equals(e1.getType(), e2.getType()) && Objects.equals(e1.getDesc(), e2.getDesc());
    }

    /**
     * 判断类型值与枚举实例是否相等。
     *
     * @param type 类型值。
     * @param e    枚举实例。
     * @return 如果类型值与枚举实例的类型值相等,返回true;否则返回false。
     */
    static boolean eq(Integer type, IEnum e) {
        if (type == null || e == null) {
            return false;
        }
        return Objects.equals(type, e.getType());
    }

    /**
     * 如果类型值与枚举相等,则执行指定函数。
     *
     * @param type 类型值。
     * @param e    枚举实例。
     * @param func 要执行的函数。
     */
    static void handleIfEqual(Integer type, IEnum e, Runnable func) {
        if (eq(type, e) && func != null) {
            func.run();
        }
    }

    /**
     * 如果两个枚举实例相等,则执行指定函数。
     *
     * @param e1   第一个枚举实例。
     * @param e2   第二个枚举实例。
     * @param func 要执行的函数。
     */
    static void handleIfEqual(IEnum e1, IEnum e2, Runnable func) {
        if (eq(e1, e2) && func != null) {
            func.run();
        }
    }

    /**
     * 如果当前枚举与指定类型值相等,则执行指定函数。
     *
     * @param type 类型值。
     * @param func 要执行的函数。
     */
    default void handleIf(Integer type, Runnable func) {
        if (eq(type, this) && func != null) {
            func.run();
        }
    }

    /**
     * 如果当前枚举与另一个枚举实例相等,则执行指定函数。
     *
     * @param dict 枚举实例。
     * @param func 要执行的函数。
     */
    default void handleIf(IEnum dict, Runnable func) {
        if (eq(dict, this) && func != null) {
            func.run();
        }
    }
}