根据对象的某个字段实现分组,字段名称作为参数传递,可以形成树形结构
工具类
package com.example.demo.util;
import org.springframework.util.CollectionUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author 星空
* @ClassName GroupUtils
* @description: 动态分组 根据传入的字段名称,按照字段的值进行分组
* @date 2024年05月29日
* @version: 1.0
*/
public class GroupUtils {
public static <T> Map<String, List<T>> groupByDynamicColumn(Object ob, List<T> list, String columnName) {
return list.stream().collect(Collectors.groupingBy(t -> groupByDynamicColumn(t, getReadMethod(columnName, ob))));
}
private static <T> String groupByDynamicColumn(T t, Method readMethod) {
if (readMethod == null) {
throw new RuntimeException("没有字段方法,字段不存在");
}
try {
return readMethod.invoke(t).toString();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
private static Method getReadMethod(String columnName, Object ob) {
try {
return new PropertyDescriptor(columnName, ob.getClass()).getReadMethod();
} catch (Exception ex) {
throw new RuntimeException("排序失败");
}
}
}
测试代码
分组的实体类
@Data
public class GroupDTO {
private String name;
private String frame1;
private String frame2;
private String frame3;
private String frame4;
private String desc;
}
分组后组建的实体类
@Data
public class GroupInfo {
private String name;
private String frame;
private String frame1;
private String frame2;
private String frame3;
private String frame4;
private String desc;
List<GroupInfo> childList = new ArrayList<>();
}
分组方法
public static List<GroupInfo> getGroupList(List<GroupDTO> groupList, List<String> columns) {
if (CollectionUtils.isEmpty(columns)|| CollectionUtils.isEmpty(groupList)) {
return new ArrayList<>();
}
String column = columns.remove(0);
// 将当前字段的值按照集合的顺序取出来,为了排序,如果由排序字段需按照排序字段排序,这里按照集合数据的顺序
List<String> keys = new ArrayList<>();
for (GroupDTO dto : groupList) {
try {
Field field = dto.getClass().getDeclaredField(column);
field.setAccessible(true);
Object ob = field.get(dto);
if (keys.contains(ob.toString())){
continue;
}
keys.add(ob.toString());
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
// 分组
Map<String, List<GroupDTO>> stringListMap = GroupUtils.groupByDynamicColumn(new GroupDTO(), groupList, column);
List<GroupInfo> results = new ArrayList<>();
// 按照顺序处理
for (String key : keys) {
GroupInfo groupInfo = new GroupInfo();
groupInfo.setFrame(key);
List<GroupDTO> dtos = stringListMap.get(key);
// 小于1 说明已经是最后一级了,所以没必要再次递归
if (columns.size() < 1){
List<GroupInfo> childs = new ArrayList<>();
for (GroupDTO dto : dtos) {
GroupInfo groupInfo1 = new GroupInfo();
BeanUtils.copyProperties(dto,groupInfo1);
childs.add(groupInfo1);
}
groupInfo.setChildList(childs);
}else {
// 递归,字段list需要重洗new一个新的list,对象传递会导致数据丢失
groupInfo.setChildList(getGroupList(dtos, new ArrayList<>(columns)));
}
results.add(groupInfo);
}
return results;
}
原数据
实现结果