一、Bean操作类
使用表达式,获取Bean中字段名,不用使用字符串或者常量方式
1.1、定义两个接口
@FunctionalInterface
public interface IGetter<T> extends Serializable {
Object get(T source);
}
@FunctionalInterface
public interface ISetter<T, U> extends Serializable {
void set(T t, U u);
}
1.2、定义Bean操作类
/**
* Bean操作类
* (1)lambda方式获取字段名
* (2)lambda方式获取类
*/
public class BeanUtil {
private final static Logger log = LoggerFactory.getLogger(BeanUtil.class);
/**
* 通过getter的方法引用获取对象类
*
* @param fn
* @param <T>
* @return
*/
public static <T> Class<T> getClassName(IGetter<T> fn) {
try {
SerializedLambda lambda = getSerializedLambda(fn);
String implClass = lambda.getImplClass();
return (Class<T>) Class.forName(implClass.replace("/","."));
} catch (Exception e) {
log.error("通过getter的方法引用获取对象类失败", e);
return null;
}
}
/**
* 通过getter的方法引用获取字段名
*/
public static <T> String getFieldName(IGetter<T> fn) {
try {
SerializedLambda lambda = getSerializedLambda(fn);
String methodName = lambda.getImplMethodName();
String prefix = null;
if (methodName.startsWith("get")) {
prefix = "get";
} else if (methodName.startsWith("is")) {
prefix = "is";
}
if (prefix == null) {
log.error("无效的getter方法: " + methodName);
}
return toLowerCaseFirstOne(methodName.replace(prefix, ""));
} catch (Exception e) {
log.error("通过getter的方法引用获取字段名失败", e);
return null;
}
}
/**
* 通过setter的方法引用获取字段名
*
* @throws Exception
*/
public static <T, U> String getFieldName(ISetter<T, U> fn) {
try {
SerializedLambda lambda = getSerializedLambda(fn);
String methodName = lambda.getImplMethodName();
if (!methodName.startsWith("set")) {
log.error("无效的setter方法:" + methodName);
}
return toLowerCaseFirstOne(methodName.replace("set", ""));
} catch (Exception e) {
log.error("通过setter的方法引用获取字段名失败", e);
return null;
}
}
/**
* 获取 lambda
*
* @param fn
* @return
* @throws Exception
*/
private static SerializedLambda getSerializedLambda(Serializable fn) throws Exception {
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
SerializedLambda lambda = (SerializedLambda) method.invoke(fn);
return lambda;
}
/**
* 字符串首字母转小写
*/
private static String toLowerCaseFirstOne(String field) {
if (Character.isLowerCase(field.charAt(0)))
return field;
else {
char firstOne = Character.toLowerCase(field.charAt(0));
String other = field.substring(1);
return new StringBuilder().append(firstOne).append(other).toString();
}
}
}
1.3、使用表达式获取字段名
String nameField=BeanUtil.getFieldName(User::getName);
二、List操作类
记录一些list操作方法:包括重复校验list(根据传入字段)获取重复数据项
public class ListUtil {
/**
* 校验集合是否存在重复数据
*
* @param list 需要校验的集合
* @param fns lambda表达式
* @param <E>
* @return true 重复 false 不重复
*/
public static <E> boolean hasRepeatData(List<E> list, IGetter<E>... fns) {
if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fns))) return false;
List<String> fieldNames = new ArrayList<>();
for (IGetter<E> fn : fns) {
fieldNames.add(BeanUtil.getFieldName(fn));
}
return hasRepeatData(list, fieldNames);
}
/**
* 校验集合是否存在重复数据
*
* @param list 需要校验的集合
* @param fieldNames 字段名集合
* @param <E>
* @return true 重复 false 不重复
*/
public static <E> boolean hasRepeatData(List<E> list, List<String> fieldNames) {
if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fieldNames))) return false;
Map<String, Long> map = list.stream().collect(Collectors.groupingBy(p -> {
String key = "";
for (String fieldName : fieldNames) {
key += String.valueOf(ReflectionUtils.getFieldValue(p, fieldName));
}
return key;
}, Collectors.counting()));
for (Map.Entry<String, Long> entry : map.entrySet()) {
if (entry.getValue() > 1L) return true;
}
return false;
}
/**
* 获取重复数据
*
* @param list 获取重复数据的集合
* @param fns lambda表达式
* @param <E>
* @return
*/
public static <E> E getRepeatData(List<E> list, IGetter<E>... fns) {
if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fns))) return null;
List<String> fieldNames = new ArrayList<>();
for (IGetter<E> fn : fns) {
fieldNames.add(BeanUtil.getFieldName(fn));
}
return getRepeatData(list, fieldNames);
}
/**
* 获取重复数据
*
* @param list 获取重复数据的集合
* @param fieldNames 字段名称集合
* @param <E>
* @return
*/
public static <E> E getRepeatData(List<E> list, List<String> fieldNames) {
if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fieldNames))) return null;
Map<String, List<E>> maps = list.stream().collect(Collectors.groupingBy(p -> {
String key = "";
for (String fieldName : fieldNames) {
key += String.valueOf(ReflectionUtils.getFieldValue(p, fieldName));
}
return key;
}));
for (Map.Entry<String, List<E>> entry : maps.entrySet()) {
if (!CollectionUtils.isEmpty(entry.getValue()) && entry.getValue().size() > 1) {
return entry.getValue().get(0);
}
}
return null;
}
}