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
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 5月以来,哪怕对市场风向再不敏感的人,也感觉到阵阵凉意。二级市场连续下挫,一级市场融资环境恶化,不论企业融资数量还...