【Java】枚举类转换封装

本文介绍了用于K-V模式枚举转换的`BaseEnum`接口,提供获取枚举值、键的静态方法。此外,还详细阐述了`EnumUtils`工具类,用于根据枚举的特定字段值查找枚举实例,支持设置忽略大小写和自定义字段名。文章通过示例展示了如何使用这两个工具类进行枚举操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 K,V枚举转换器

当枚举为K,V模式的时候,通过K,V获取对应的枚举对象需要继承BaseEnum


import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public interface BaseEnum<K, V> {

    K getKey();

    V getValue();

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> List<K> getKeysByEnum(Class<T> enumClass) {
        return Arrays.stream(enumClass.getEnumConstants())
                .map(BaseEnum::getKey)
                .collect(Collectors.toList());
    }

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> List<V> getValuesByEnum(Class<T> enumClass) {
        return Arrays.stream(enumClass.getEnumConstants())
                .map(BaseEnum::getValue)
                .collect(Collectors.toList());
    }

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> T getEnumByKey(Class<T> enumClass, K key) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(t -> t.getKey().equals(key))
                .findFirst()
                .orElseThrow(() -> new RuntimeException(""));
    }

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> T getEnumByValue(Class<T> enumClass, V value) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(t -> t.getValue().equals(value))
                .findFirst()
                .orElseThrow(() -> new RuntimeException(""));
    }

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> V getValueByKey(Class<T> enumClass, K key) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(t -> t.getKey().equals(key))
                .findFirst()
                .orElseThrow(() -> new RuntimeException(""))
                .getValue();
    }

    static <K, V, T extends Enum<?> & BaseEnum<K, V>> K getKeyByValue(Class<T> enumClass, V value) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(t -> t.getValue().equals(value))
                .findFirst()
                .orElseThrow(() -> new RuntimeException(""))
                .getKey();
    }
}

2 属性与枚举转换器

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class EnumUtils {

    /**
     * 枚举默认名称字段名
     */
    private static final String ENUM_DEFAULT_FIELD_NAME = "name";

    /**
     * 空字符对象的字符串格式
     */
    private static final String NULL_STRING = "null";

    /**
     * 比较枚举唯一值时是否忽略大小写
     */
    private static boolean IGNORE_CASE = true;

    /**
     * 枚举唯一标识的字段名称
     */
    private static String FIELD_NAME = ENUM_DEFAULT_FIELD_NAME;

    /**
     * 这是比较枚举唯一值是是否忽略大小写
     *
     * @param ignoreCase true-忽略;false-不忽略
     */
    public void setIgnoreCase(boolean ignoreCase) {
        EnumUtils.IGNORE_CASE = ignoreCase;
    }

    /**
     * 设置枚举枚举唯一标识字段名称
     *
     * @param fieldName 字段名称
     */
    public void setFieldName(String fieldName) {
        EnumUtils.FIELD_NAME = fieldName;
    }

    /**
     * 获取枚举项列表。<br/>
     * 等同枚举的<code>values()</code>方法。
     *
     * @param enumClass 枚举类类型
     * @param <E>       枚举类类型
     * @return 枚举项列表
     */
    public static <E extends Enum<E>> List<E> getInstances(Class<E> enumClass) {
        E[] enumItemArray = enumClass.getEnumConstants();
        return Arrays.asList(enumItemArray);
    }

    /**
     * 根据指定的任意字段的值标识符来查找对应的枚举项。如果该字段的值标识符支持重复,则可能返回多个枚举项实例。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param fieldName  待查找匹配的字段名称
     * @param <E>        枚举类类型
     * @return 匹配的枚举项列表
     */
    public static <E extends Enum<E>> List<E> getInstances(Class<E> enumClass, String identifier, String fieldName) {
        List<E> enumList = new ArrayList<E>();
        E[] enumItemArray = enumClass.getEnumConstants();
        if (enumItemArray.length == 0) {
            return enumList;
        }
        try {
            for (E enumItem : enumItemArray) {
                Field field = null;
                if (ENUM_DEFAULT_FIELD_NAME.equals(fieldName)) {
                    field = Enum.class.getDeclaredField(fieldName);
                } else {
                    field = enumItem.getClass().getDeclaredField(fieldName);
                }
                if (field == null) {
                    continue;
                }
                /*if (field.isEnumConstant()) {
                    break;
                }*/
                field.setAccessible(true);
                String value = String.valueOf(field.get(enumItem));
                boolean isEquals = (IGNORE_CASE && value.equalsIgnoreCase(identifier)) || value.equals(identifier);
                if (isEquals) {
                    enumList.add(enumItem);
                    continue;
                }
            }
        } catch (Exception e) {
            return enumList;
        }
        return enumList;
    }

    /**
     * 根据指定的全局配置字段[{@value FIELD_NAME}]的值表示来查找对应的枚举项。如果该字段的值标识符支持重复,则可能返回多个枚举项实例。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param <E>        枚举类类型
     * @return 匹配的枚举项列表
     * @see #getInstances(Class, String, String)
     */
    public static <E extends Enum<E>> List<E> getInstances(Class<E> enumClass, String identifier) {
        return getInstances(enumClass, identifier, FIELD_NAME);
    }

    /**
     * 根据指定的任意字段的值标识符来查找对应的枚举项。并返回首个匹配的枚举项,如果没有匹配则返回null。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param fieldName  待查找匹配的字段名称
     * @param <E>        枚举类类型
     * @return 首个匹配的枚举项实例或null
     * @see #getInstances(Class, String, String)
     */
    public static <E extends Enum<E>> E getInstance(Class<E> enumClass, String identifier, String fieldName) {
        List<E> enumItemList = getInstances(enumClass, identifier, fieldName);
        return enumItemList.size() > 0 ? enumItemList.get(0) : null;
    }

    /**
     * 根据指定的全局配置字段[{@value FIELD_NAME}]的值表示来查找对应的枚举项,并返回第一个匹配的枚举项,如果没有匹配则返回null。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param <E>        枚举类类型
     * @return 首个匹配的枚举项实例或null
     * @see #getInstance(Class, String)
     */
    public static <E extends Enum<E>> E getInstance(Class<E> enumClass, String identifier) {
        return getInstance(enumClass, identifier, FIELD_NAME);
    }

    /**
     * 根据指定的任意字段的值标识符来查找对应的枚举项。并返回首个匹配的枚举项,如果没有匹配则返回指定的默认枚举对象。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass    枚举类类型
     * @param identifier   值标识符
     * @param fieldName    待查找匹配的字段名称
     * @param enumInstance 默认返回枚举对象
     * @param <E>          枚举类类型
     * @return 首个匹配的枚举项实例或默认返回枚举对象
     * @see #getInstances(Class, String, String)
     */
    public static <E extends Enum<E>> E getInstanceOrDefault(Class<E> enumClass, String identifier, String fieldName, E enumInstance) {
        List<E> enumItemList = getInstances(enumClass, identifier, fieldName);
        return enumItemList.size() > 0 ? enumItemList.get(0) : enumInstance;
    }

    /**
     * 根据指定的全局配置字段[{@value FIELD_NAME}]的值表示来查找对应的枚举项,并返回第一个匹配的枚举项,如果没有匹配则指定的默认枚举对象。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass    枚举类类型
     * @param identifier   值标识符
     * @param enumInstance 默认返回枚举对象
     * @param <E>          枚举类类型
     * @return 首个匹配的枚举项实例或默认返回枚举对象
     * @see #getInstanceOrDefault(Class, String, String, Enum)
     */
    public static <E extends Enum<E>> E getInstanceOrDefault(Class<E> enumClass, String identifier, E enumInstance) {
        return getInstanceOrDefault(enumClass, identifier, FIELD_NAME, enumInstance);
    }

    /**
     * 判断指定的值标识符是否是一个枚举实例;根据指定的字段进行比较匹配。同时如果给定的值标识为空,指定是否允许忽略。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param fieldName  待查找匹配的字段名称
     * @param ignoreNull 是否忽略空标识符
     * @param <E>        枚举类类型
     * @return 如果忽略空,则传入是空则返回true;如果不忽略空,如果是枚举项则返回true,否则或异常则返回false
     */
    public static <E extends Enum<E>> boolean isEnumInstance(Class<E> enumClass, String identifier, String fieldName, boolean ignoreNull) {
        if (ignoreNull && NULL_STRING.equals(String.valueOf(identifier))) {
            return true;
        }
        try {
            E[] enumItemArray = enumClass.getEnumConstants();
            for (E enumItem : enumItemArray) {
                Field field = null;
                if (ENUM_DEFAULT_FIELD_NAME.equals(fieldName)) {
                    field = Enum.class.getDeclaredField(fieldName);
                } else {
                    field = enumItem.getClass().getDeclaredField(fieldName);
                }
                if (field == null) {
                    return false;
                }
                field.setAccessible(true);
                String value = String.valueOf(field.get(enumItem));
                boolean isEnum = (IGNORE_CASE && value.equalsIgnoreCase(identifier)) || value.equals(identifier);
                if (isEnum) {
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    /**
     * 判断指定的值标识符是否是一个枚举实例;根据默认配置字段{@value FIELD_NAME}进行比较匹配。同时如果给定的值标识为空,指定是否允许忽略。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param ignoreNull 是否忽略空标识符
     * @param <E>        枚举类类型
     * @return 如果忽略空,则传入是空则返回true;如果不忽略空,如果是枚举项则返回true,否则或异常则返回false
     */
    public static <E extends Enum<E>> boolean isEnumInstance(Class<E> enumClass, String identifier, boolean ignoreNull) {
        return isEnumInstance(enumClass, identifier, FIELD_NAME, ignoreNull);
    }

    /**
     * 判断指定的值标识符是否是一个枚举实例;根据指定的字段进行比较匹配,如果输入的值标识符为空则返回true。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param fieldName  待查找匹配的字段名称
     * @param <E>        枚举类类型
     * @return 如果传入是空则返回true;如果不为空,如果是枚举项则返回true,否则或异常则返回false
     */
    public static <E extends Enum<E>> boolean isEnumInstance(Class<E> enumClass, String identifier, String fieldName) {
        return isEnumInstance(enumClass, identifier, fieldName, true);
    }

    /**
     * 判断指定的值标识符是否是一个枚举实例;根据默认配置的字段{@value FIELD_NAME}进行比较匹配,如果输入的值标识符为空则返回true。<br/>
     * 会根据全局配置的是否忽略大小写[{@value IGNORE_CASE}]来进行值的比较。
     *
     * @param enumClass  枚举类类型
     * @param identifier 值标识符
     * @param <E>        枚举类类型
     * @return 如果传入是空则返回true;如果不为空,如果是枚举项则返回true,否则或异常则返回false
     */
    public static <E extends Enum<E>> boolean isEnumInstance(Class<E> enumClass, String identifier) {
        return isEnumInstance(enumClass, identifier, FIELD_NAME, true);
    }



}

3 使用样例

import java.util.List;

public enum TestEnum implements BaseEnum<String, String>{

    A("a","1"),
    B("a","2"),
    C("a","3")
    ;

    private final String key;
    private final String value;

    public static void main(String[] args) {
        // 通用的枚举处理器
        List<TestEnum> instancesByKey = EnumUtils.getInstances(TestEnum.class, "a","key");
        List<TestEnum> instancesByValue = EnumUtils.getInstances(TestEnum.class, "1","value");
        TestEnum instanceByName = EnumUtils.getInstance(TestEnum.class, "a");
        System.out.println(instancesByKey);
        System.out.println(instancesByValue);
        System.out.println(instanceByName);
        // kv处理器
        TestEnum enumByValue = BaseEnum.getEnumByValue(TestEnum.class, "a");
        System.out.println(enumByValue);
    }


    TestEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }


    @Override
    public String getKey() {
        return key;
    }

    @Override
    public String getValue() {
        return value;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值