最近有需求,需要根据配置文件,
动态的 过滤+聚合 数据
想想就写了动态的lambda,方便使用。
目前只有 filter和group。并且没有测试过性能。
如果大家使用的话,先将就一下,或者自己改改。
一,主要方法类
通过反射,来组装lambda。
主要使用方法:
getFiledValue
getDataListFilter
getDataListGroup
package com.leadtrans.report.common; import org.springframework.aop.support.AopUtils; import org.springframework.context.ApplicationContext; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.*; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author: Tyler * @createDate: 2021/12/9 */ public class ReflectionUtil { /** * 调用示例 * public ApiResponse<String> test() throws Exception { * Class[] argsType=new Class[]{Class.forName("java.lang.String")}; * Object[] args=new Object[]{"hello"}; * ReflectionUtil.invokeMethod(new ReportImpl(),"Test",argsType,args); * return new ApiResponse().Success("str"); * } * @param owner 类的实例 * @param methodName 方法名 * @param argsClass 参数类型 * @param args 参数 * @return * @throws Exception */ public static Object invokeMethod(Object owner,String methodName,Class[] argsClass,Object[] args) throws Exception{ Object objRtn=null; Class ownerClass = owner.getClass(); Method method = ownerClass.getMethod(methodName, argsClass); objRtn = method.invoke(owner, args); return objRtn; } public static Object getFiledValue(Object obj,String filedName){ Object objValue=null; try { Field field = obj.getClass().getDeclaredField(filedName); field.setAccessible(true); objValue = field.get(obj); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } finally { return objValue; } } /** * Lambda 动态 Filter * @param list 数据 * @param map 过滤字段/过滤值 * @param <T> * @return */ public static <T> List<T> getDataListFilter(List<T> list, Map<String, Object> map) { Supplier<Stream<T>> st = () -> list.stream(); for (Map.Entry<String, Object> item : map.entrySet()) { Supplier<Stream<T>> stFilter = st; st = () -> stFilter.get().filter(x -> ReflectionUtil.getFiledValue(x, item.getKey()) == item.getValue()); } List<T> rList = st.get().collect(Collectors.toList()); return rList; } /** * Lambda 动态 Group * @param list 数据 * @param groups 聚合字段 * @param <T> * @return */ public static <T> Map<String, List<T>> getDataListGroup(List<T> list,List<String> groups){ Map<String, List<T>> map= list.stream().collect(Collectors.groupingBy(x -> { String groupItem =""; for (String y : groups){ groupItem+=ReflectionUtil.getFiledValue(x, y)+"_"; } return groupItem; })); return map; } }
二,测试
@Test public void test() throws NoSuchFieldException, IllegalAccessException { //filter 条件 Map<String, Object> map = new HashMap<>(); map.put("fileType", 1); map.put("reportName", "b"); //原数据 List<FileTypeVO> list = new ArrayList<>() { { add(new FileTypeVO(1, "a", "aPath")); add(new FileTypeVO(1, "b", "bPath")); add(new FileTypeVO(1, "b", "cPath")); add(new FileTypeVO(4, "c", "dPath")); } }; //group 字段 List<String> groups=new ArrayList<>(){{ add("reportName"); add("filePath"); }}; //filter 数据 List<FileTypeVO> rList = ReflectionUtil.getDataListFilter(list, map); //group 数据 Map<String,List<FileTypeVO>> rMap=ReflectionUtil.getDataListGroup(rList,groups); System.out.println(rList.size()); }
测试实体:FileTypeVo
package com.leadtrans.report.model; import io.swagger.annotations.ApiModelProperty; /** * @author: Tyler * @createDate: 2021/11/17 */ public class FileTypeVO { private int fileType; private String reportName; private String filePath; private String order; public FileTypeVO(){} public FileTypeVO(int fileType,String reportName,String filePath){ this.fileType=fileType; this.reportName=reportName; this.filePath=filePath; } public FileTypeVO(int fileType,String reportName,String filePath,String order){ this(fileType,reportName,filePath); this.order=order; } public int getFileType() { return fileType; } public void setFileType(int fileType) { this.fileType = fileType; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public String getReportName() { return reportName; } public void setReportName(String reportName) { this.reportName = reportName; } public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } }