利用ai生成了一个通用的树形工具类,简单修改了一下
java版本:
import lombok.Getter;
import lombok.Setter;
import java.util.*;
/**
* @author CF
* @date 2025/5/8 上午10:42
* @description: 树形结构工具类
*/
public class TreeUtils {
public static <T> List<T> buildTree(List<T> list, Config config) {
config = config == null ? new Config() : config;
// 创建节点映射表
Map<Object, T> nodeMap = new HashMap<>();
// 获取反射工具实例
ReflectUtils<T> reflectUtils = new ReflectUtils<>();
for (T node : list) {
// 初始化子节点
reflectUtils.setFieldValue(node, config.getChildrenKey(), new ArrayList<>());
// 将节点存入映射表
Object id = reflectUtils.getFieldValue(node, config.getIdKey());
nodeMap.put(id, node);
}
// 构建树结构
List<T> tree = new ArrayList<>();
for (T node : nodeMap.values()) {
Object parentId = reflectUtils.getFieldValue(node, config.getParentKey());
// 判断是否为根节点
if (parentId.equals(-1) || !nodeMap.containsKey(parentId)) {
tree.add(node);
} else {
T parent = nodeMap.get(parentId);
// 将节点添加到父节点的子节点列表中
List<T> children = reflectUtils.getFieldValue(parent, config.getChildrenKey());
children.add(node);
}
}
return tree;
}
// 配置类,用于存储 idKey、parentKey 和 childrenKey
@Getter
@Setter
public static class Config {
private String idKey = "id";
private String parentKey = "parentId";
private String childrenKey = "children";
public Config() {
}
public Config(String idKey, String parentKey, String childrenKey) {
this.idKey = idKey;
this.parentKey = parentKey;
this.childrenKey = childrenKey;
}
}
// 反射工具类,用于通过反射获取和设置对象的属性值
private static class ReflectUtils<T> {
@SuppressWarnings("unchecked")
public <V> V getFieldValue(T object, String fieldName) {
try {
java.lang.reflect.Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (V) field.get(object);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void setFieldValue(T object, String fieldName, Object value) {
try {
java.lang.reflect.Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
测试数据
js版本
function buildTree(list, config = {}) {
const {
idKey = 'id',
parentKey = 'parentId',
childrenKey = 'children'
} = config;
// 创建节点映射表
const nodeMap = new Map();
list.forEach(node => {
node[childrenKey] = []; // 初始化子节点
nodeMap.set(node[idKey], node);
});
// 构建树结构
const tree = [];
for (const node of nodeMap.values()) {
const parentId = node[parentKey];
if (parentId === -1 || !nodeMap.has(parentId)) { // 根节点条件根据业务调整
tree.push(node);
} else {
const parent = nodeMap.get(parentId);
parent[childrenKey].push(node);
}
}
return tree;
}
测试数据
// 原始数据(需包含 id 和 parentId 字段)
const flatList = [
{ id: 1, name: 'Node 1', parentId: -1,code:2 },
{ id: 2, name: 'Node 1-1', parentId: 1 ,code:3},
{ id: 3, name: 'Node 1-2', parentId: 1,code:4 },
{ id: 4, name: 'Node 2', parentId: -1 ,code:5}
];
// 生成树形结构
const treeData = buildTree(flatList, {
idKey: 'id', // 对应节点ID字段
parentKey: 'parentId',// 对应父节点ID字段
childrenKey: 'children' // 生成的子节点字段
});
console.log(treeData);
1456

被折叠的 条评论
为什么被折叠?



