【Java开发工具类】集合数组数据抽取工具类

本文介绍了一个Java工具类,用于从对象数组集合中抽取特定字段数据,包括去重功能。通过反射技术,可以实现从Object数组中提取指定字段形成新的数组或Map结构。同时,提供了两种不同的Map转换方法,一种将对象数组转换为Map,以某个字段为key,对象为value;另一种则是根据对象的某个字段值进行分组,形成以字段值为key,包含相同字段值的对象列表为value的Map。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集合数组数据抽取工具类

  • 功能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;

    /**
     * 订单号
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值