读取json生成List集合,然后转为enum枚举

动态改变枚举类的枚举值,配置方式实现枚举_cy谭的博客-CSDN博客_动态枚举类

1,先做一个enum类

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)  
public enum PlanFilter{
    //设定空的enum   
    ;

    //enum对象包含的属性
    public final String featGroup;
    public final String nFeat;
    public final String key;
    ...


    @Override
    public String toString(){
        return this.key +
            "{" +
            ...
    }

}

2,对象类

@Getter
@Setter
public class FilterInfo {
  public String featGroup;
  public String nFeat;
  ...

}

3,读json的service类 FilterInfoService

private static String path = "*****";

public static List<FilterInfo> getPlanFilter(){
    List<FilterInfo> = new ArrayList<>();
    
    try{
        File json = new File(path);
        ObjectMapper mapper = new ObjectMapper();
        List<Object> dataList = mapper.readValue(json, new TypeReference<List<Object>>(){});
        for(Object obj : dataList) {
            Map<String, Object> dataMap = (Map<String, Object>) obj;
            temp1 = (String) dataMap.get(FEATURE_GROUP);

4,把list转化为enum,DynamicEnumUtil,核心类,这个类无需修改,直接用即可,对外接口 

DynamicEnumUtil.addEnum()

package com.xiong.test.dynamicenum;
 
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
 
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
/**
 * 动态新增枚举工具类
 */
public class DynamicEnumUtil {
    private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
 
    private static void setFailsafeFieldValue(Field field, Object target, Object value) throws NoSuchFieldException,
            IllegalAccessException {
 
        // let's make the field accessible
        field.setAccessible(true);
 
        // next we change the modifier in the Field instance to
        // not be final anymore, thus tricking reflection into
        // letting us modify the static final field
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        int modifiers = modifiersField.getInt(field);
 
        // blank out the final bit in the modifiers int
        modifiers &= ~Modifier.FINAL;
        modifiersField.setInt(field, modifiers);
 
        FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
        fa.set(target, value);
    }
 
    private static void blankField(Class<?> enumClass, String fieldName) throws NoSuchFieldException,
            IllegalAccessException {
        for (Field field : Class.class.getDeclaredFields()) {
            if (field.getName().contains(fieldName)) {
                AccessibleObject.setAccessible(new Field[] { field }, true);
                setFailsafeFieldValue(field, enumClass, null);
                break;
            }
        }
    }
 
    private static void cleanEnumCache(Class<?> enumClass) throws NoSuchFieldException, IllegalAccessException {
        blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
        blankField(enumClass, "enumConstants"); // IBM JDK
    }
 
    private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes)
            throws NoSuchMethodException {
        Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
        parameterTypes[0] = String.class;
        parameterTypes[1] = int.class;
        System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
        return reflectionFactory.newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
    }
 
    private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes,
                                   Object[] additionalValues) throws Exception {
        Object[] parms = new Object[additionalValues.length + 2];
        parms[0] = value;
        parms[1] = Integer.valueOf(ordinal);
        System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
        return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
    }
 
    /**
     * 判断枚举是否已存在
     * @param values
     * @param enumName
     * @param <T>
     * @return
     */
    public static <T extends Enum<?>> boolean contains(List<T> values, String enumName){
        for (T value : values) {
            if (value.name().equals(enumName)) {
                return true;
            }
        }
        return false;
    }
 
 
    /**
     * Add an enum instance to the enum class given as argument
     *
     * @param <T> the type of the enum (implicit)
     * @param enumType the class of the enum to be modified
     * @param enumName the name of the new enum instance to be added to the class.
     */
    @SuppressWarnings("unchecked")
    public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName, Class<?>[] additionalTypes, Object[] additionalValues) {
 
        // 0. Sanity checks
        if (!Enum.class.isAssignableFrom(enumType)) {
            throw new RuntimeException("class " + enumType + " is not an instance of Enum");
        }
 
        // 1. Lookup "$VALUES" holder in enum class and get previous enum instances
        Field valuesField = null;
        Field[] fields = enumType.getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().contains("$VALUES")) {
                valuesField = field;
                break;
            }
        }
        AccessibleObject.setAccessible(new Field[] { valuesField }, true);
 
        try {
 
            // 2. Copy it
            T[] previousValues = (T[]) valuesField.get(enumType);
            List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
 
            // 3. build new enum
            T newValue = (T) makeEnum(enumType, enumName, values.size(), additionalTypes, additionalValues);
 
            if(contains(values,enumName)){
                System.out.println("Enum:" + enumName + " 已存在");
                return;
            }
 
            // 4. add new value
            values.add(newValue);
 
            // 5. Set new values field
            setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
 
            // 6. Clean enum cache
            cleanEnumCache(enumType);
 
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage(), e);
        }
    }
 
 
}

5,在FilterInfoService类里面,添加(4)的接口


    /**
     * 
     * @param enumName 枚举名
     * @param code 枚举项1
     * @param name 枚举项2
     */
    private static void addTestEnum(String enumName, String code, String name) {//list有多少个参数,这里就需要有多少个参数,一一对应
        DynamicEnumUtil.addEnum(TestEnum.class, enumName, new Class<?>[]
                {String.class, String.class}, //这里也需要一一对应
                new Object[]{code, name}); //这里也是
    }

6,然后把list转化为enum

/**
 * Convert list to enum
 */
public static void listToEnum(){
    List<FilterInfo> filterinfo = getPlanFilter(); //(3)中的方法
    if(filterInfo != null && filterInfo.size() > 0) {
        //LIST -> Enum
        for(int i = 0; i < filterInfo.sezi(); i++) {
            addEnum(filterInfo.get(i).featGroup,
                    filterInfo.get(i).nFeat,
                    ...);
        }
    }
}

7,ok了。直接调用listToEnum()就可以了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值