集合数组数据抽取工具类
- 功能1:抽取对象数组中的某一个字段形成的数据(去重)
1、某一字段数据抽取
描述:从一个Object对象数组中,提取Object对象中A字段形成的数组
反射工具类:
import com.google.common.base.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @description 反射工具类
* @author: wilsonMeng
* @create: 2021-01-15 11:06
**/
@Slf4j
public class ReflectUtils {
public static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
public static Method[] getAccessibleMethods(Class<?> clazz) {
return clazz == null ? EMPTY_METHOD_ARRAY : clazz.getDeclaredMethods();
}
//注:Optional引入的不是jdk的包 而是com.google.common.base.Optional
public static Optional<Method> getAccessibleMethod(final Object obj,
final String methodName,
final Class<?>... parameterTypes) {
for (Class<?> c = obj.getClass(); c != Object.class; c = c.getSuperclass()) {
try {
Method method = c.getDeclaredMethod(methodName, parameterTypes);
method.setAccessible(true);
return Optional.of(method);
} catch (NoSuchMethodException e) {
// Method不在当前类定义,继续向上转型
}
}
return Optional.absent();
}
public static Optional<Field> getAccessibleField(final Object obj,
final String fieldName) {
for (Class<?> c = obj.getClass(); c != Object.class; c = c.getSuperclass()) {
try {
Field field = c.getDeclaredField(fieldName);
field.setAccessible(true);
return Optional.of(field);
} catch (NoSuchFieldException e) {
// Field不在当前类定义,继续向上转型
}
}
return Optional.absent();
}
public static Optional<Object> getFieldValue(final Object obj, final String fieldName) {
Optional<Field> field = getAccessibleField(obj, fieldName);
if (!field.isPresent()) {
throw new IllegalArgumentException("Could not find field ["
+ fieldName + "] on target [" + obj + "]");
}
try {
return Optional.fromNullable(field.get().get(obj));
} catch (IllegalAccessException e) {
log.error("不可能抛出的异常", e);
}
return Optional.absent();
}
//与getFieldValue比较, 字段不存在不会抛异常
public static Optional<Object> safeGetFieldValue(final Object obj, final String fieldName) {
Optional<Field> field = getAccessibleField(obj, fieldName);
if (!field.isPresent()) {
return Optional.absent();
}
try {
return Optional.fromNullable(field.get().get(obj));
} catch (IllegalAccessException e) {
log.error("不可能抛出的异常", e);
}
return Optional.absent();
}
public static void setFieldValue(final Object obj, final String fieldName,
final Object value) {
Optional<Field> field = getAccessibleField(obj, fieldName);
if (!field.isPresent()) {
throw new IllegalArgumentException("Could not find field ["
+ fieldName + "] on target [" + obj + "]");
}
try {
field.get().set(obj, value);
} catch (IllegalAccessException e) {
log.error("不可能抛出的异常", e);
}
}
//与setFieldValue比较, 字段不存在不会抛异常
public static void safeSetFieldValue(final Object obj, final String fieldName,
final Object value) {
Optional<Field> field = getAccessibleField(obj, fieldName);
if (!field.isPresent()) {
return;
}
try {
field.get().set(obj, value);
} catch (IllegalAccessException e) {
log.error("不可能抛出的异常", e);
}
}
public static Object invokeMethod(final Object obj,
final String methodName,
final Class<?>[] parameterTypes,
final Object[] args) {
Optional<Method> method = getAccessibleMethod(obj, methodName, parameterTypes);
if (!method.isPresent()) {
throw new IllegalArgumentException("Could not find method ["
+ methodName + "] on target [" + obj + "]");
}
try {
return method.get().invoke(obj, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Object invokeGetter(Object obj, String propertyName) {
String getterMethodName = "get" + StringUtils.capitalize(propertyName);
return invokeMethod(obj, getterMethodName, new Class[] {},
new Object[] {});
}
public static void invokeSetter(Object obj, String propertyName, Object value) {
invokeSetter(obj, propertyName, value, null);
}
public static void invokeSetter(Object obj, String propertyName,
Object value, Class<?> propertyType) {
Class<?> type = propertyType != null ? propertyType : value.getClass();
String setterMethodName = "set" + StringUtils.capitalize(propertyName);
invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });
}
public static Object getFieldValue(Object object, Field field)
{
try {
field.setAccessible(true);// 设置些属性是可以访问的
return field.get(object);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
数据抽取工具类:
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @description 数据抽取工具类
* @author: wilsonMeng
* @create: 2021-01-15 11:03
**/
@Slf4j
public class ExtractUtils {
/**
* 从复杂结构列表中抽取出指定字段的列表
*
* @param list 源数据列表
* @param fieldName 欲抽取字段名
* @param clz 抽取字段类型
* @return 去重结果
*/
public static <T, R> List<R> extractField(List<T> list, String fieldName, Class<R> clz) {
if (CollectionUtils.isEmpty(list) || StringUtils.isBlank(fieldName)) {
return Collections.emptyList();
}
Function<T, R> func = (item) -> {
Object obj = null;
try {
// 注:ReflectUtils工具类是自定义的工具类
obj = ReflectUtils.invokeGetter(item, fieldName);
} catch (Exception e) {
log.info("extractField list:{}, fieldName:{}, type:{} error->", list, fieldName, clz, e);
// 可抛出自定义业务异常
// throw new SysException("反射处理异常");
throw e;
}
return (R) obj;
};
return extractField(list, func);
}
public static <T, R> List<R> extractField(List<T> list, Function<T, R> func) {
if (CollectionUtils.isEmpty(list)) {
return Collections.emptyList();
}
return list.stream().map(func).filter(Objects::nonNull).distinct().collect(Collectors.toList());
}
}
功能测试
PayOrderReqVo对象数组,提取其中字段orderNo形成的数组。
PayOrderReqVo结构:
public class PayOrderReqVo extends TradeReqVo {
private static final long serialVersionUID = -6973527623323791153L;
/**
* 订单号