美文网首页
LambdaReflectUtil

LambdaReflectUtil

作者: LoWang | 来源:发表于2020-11-23 17:56 被阅读0次
    package com.test;
    
    import java.beans.Introspector;
    import java.io.Serializable;
    import java.lang.invoke.SerializedLambda;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Objects;
    import java.util.function.Function;
    
    import org.apache.commons.collections.MapUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.util.ReflectionUtils;
    
    import com.google.common.base.CaseFormat;
    
    import lombok.Data;
    import lombok.RequiredArgsConstructor;
    import lombok.Setter;
    
    public class LambdaReflectUtil {
    
        public static void main(String[] args) {
    
            Student st = new Student();
            String fieldName = LambdaReflectUtil.getName(Student::getStudentName);
            System.out.println(fieldName);
    
            fieldName = LambdaReflectUtil.getUnderscoreName(Student::getStudentName);
            System.out.println(fieldName);
            st.setStudentName("张三");
            st.setId(201L);
            Object obj = BeanParamBuilder.of(st).checkAndBuild(Student::getStudentName).checkAndBuild(Student::getId)
                .set("ss.classId", 999L).buildMap();
            System.out.println(obj);
    
            obj = BeanParamBuilder.of(st).checkAndBuild(Student::getStudentName).checkAndBuild(Student::getId)
                .set("ss.classId", 999L).buildUnderscoreMap();
            System.out.println(obj);
        }
    
        @RequiredArgsConstructor(staticName = "of")
        public static class BeanParamBuilder<T> {
    
            private final T t;
            @Setter
            private String prefix;
            private Map<String, Object> params = new HashMap<>();
    
            public BeanParamBuilder<T> checkAndBuild(TypeFunction<T, ?> fn) {
                String name = LambdaReflectUtil.getName(fn);
                Field field = ReflectionUtils.findField(t.getClass(), name);
                if (Objects.nonNull(field)) {
                    ReflectionUtils.makeAccessible(field);
                    Object value = ReflectionUtils.getField(field, t);
                    if (StringUtils.isNotBlank(prefix)) {
                        name = String.format("%s_%s", prefix, name);
                    }
                    params.put(name, value);
                }
                return this;
            }
    
            public BeanParamBuilder<T> set(String key, Object value) {
                key = key.replaceAll("[.]", "_");
                params.put(key, value);
                return this;
            }
    
            public Map<String, Object> buildMap() {
                return params;
            }
    
            public Map<String, Object> buildUnderscoreMap() {
                if (MapUtils.isNotEmpty(params)) {
                    Map<String, Object> converted = new HashMap<>(params.size());
                    params.entrySet().stream().forEach(entry -> {
                        converted.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey()),
                            entry.getValue());
                    });
                    return converted;
                } else {
                    return Collections.emptyMap();
                }
            }
    
        }
    
        public static <T> String getUnderscoreName(SFunction<T, ?> fn) {
            // 从function取出序列化方法
            Method writeReplaceMethod;
            try {
                writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
    
            // 从序列化方法取出序列化的lambda信息
            boolean isAccessible = writeReplaceMethod.canAccess(fn);
            writeReplaceMethod.setAccessible(Boolean.TRUE);
            SerializedLambda serializedLambda;
            try {
                serializedLambda = (SerializedLambda)writeReplaceMethod.invoke(fn);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            writeReplaceMethod.setAccessible(isAccessible);
    
            // 从lambda信息取出method、field、class等
            String fieldName = serializedLambda.getImplMethodName().substring("get".length());
            fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
            return fieldName.replaceAll("[A-Z]", "_$0").toLowerCase();
        }
    
        public static <T, R> String getName(TypeFunction<T, R> fn) {
            return TypeFunction.getLambdaColumnName(fn);
        }
    
        @Data
        public static class Student {
            private Long id;
            private String studentName;
            private String studentAge;
        }
    
        @FunctionalInterface
        public static interface SFunction<T, R> extends Function<T, R>, Serializable {}
    
        @FunctionalInterface
        public static interface TypeFunction<T, R> extends Serializable, Function<T, R> {
    
            /**
             * 获取列名称
             * 
             * @param lambda
             * @return String
             */
            static String getLambdaColumnName(Serializable lambda) {
                try {
                    Method method = lambda.getClass().getDeclaredMethod("writeReplace");
                    method.setAccessible(Boolean.TRUE);
                    SerializedLambda serializedLambda = (SerializedLambda)method.invoke(lambda);
                    String getter = serializedLambda.getImplMethodName();
                    String fieldName = Introspector.decapitalize(getter.replace("get", ""));
                    return fieldName;
                } catch (ReflectiveOperationException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:LambdaReflectUtil

          本文链接:https://www.haomeiwen.com/subject/rwuviktx.html