java树结构实例
` 提示:仅供参考
一、测试实体类
import lombok.Data;
import java.util.List;
/**
* 测试实体类
*/
@Data
public class Catalog {
/**
* 唯一编号 uuid
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 父节点id
*/
private String parentId;
/**
* 子节点(数据库中不存在该字段,仅用于传输数据使用)
*/
private List<?> children;
// 省略 get set
}
二、结构树代码
1.代码
import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.reflect.FieldUtils;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class TreeExample {
/**
* 把列表转换为树结构
*
* @param originalList 原始list数据
* @param keyName 作为唯一标示的字段名称
* @return 组装后的集合
*/
public static <T> List<T> getTree(List<T> originalList, String keyName) throws Exception {
String parentFieldName = "parentId";
String childrenFieldName = "children";
// 获取根节点,即找出父节点为空的对象
List<T> topList = new ArrayList<>();
for (int i = 0; i < originalList.size(); i++) {
T t = originalList.get(i);
String parentId = BeanUtils.getProperty(t, parentFieldName);
if (StringUtils.isBlank(parentId)) {
topList.add(t);
}
}
// 将根节点从原始list移除,减少下次处理数据
originalList.removeAll(topList);
// 递归封装树
fillTree(topList, originalList, keyName, parentFieldName, childrenFieldName);
return topList;
}
/**
* 封装树
*
* @param parentList 要封装为树的父对象集合
* @param originalList 原始list数据
* @param keyName 作为唯一标示的字段名称
* @param parentFieldName 模型中作为parent字段名称
* @param childrenFieldName 模型中作为children的字段名称
*/
public static <T> void fillTree(List<T> parentList, List<T> originalList, String keyName, String parentFieldName, String childrenFieldName) throws Exception {
for (int i = 0; i < parentList.size(); i++) {
List<T> children = fillChildren(parentList.get(i), originalList, keyName, parentFieldName, childrenFieldName);
if (children.isEmpty()) {
continue;
}
originalList.removeAll(children);
fillTree(children, originalList, keyName, parentFieldName, childrenFieldName);
}
}
/**
* 封装子对象
*
* @param parent 父对象
* @param originalList 待处理对象集合
* @param keyName 作为唯一标示的字段名称
* @param parentFieldName 模型中作为parent字段名称
* @param childrenFieldName 模型中作为children的字段名称
*/
public static <T> List<T> fillChildren(T parent, List<T> originalList, String keyName, String parentFieldName, String childrenFieldName) throws Exception {
List<T> childList = new ArrayList<>();
String parentId = BeanUtils.getProperty(parent, keyName);
for (int i = 0; i < originalList.size(); i++) {
T t = originalList.get(i);
String childParentId = BeanUtils.getProperty(t, parentFieldName);
if (parentId.equals(childParentId)) {
childList.add(t);
}
}
if (!childList.isEmpty()) {
FieldUtils.writeDeclaredField(parent, childrenFieldName, childList, true);
}
return childList;
}
}
2.实例
代码如下(示例):
/**
* 测试 一共有六个Catalog
* 其中:name1下面有三个子节点:name2、name3、name4
* name2下面有两个子节点:name5、name6
*/
public static void main(String[] args) {
List<Catalog> list = new ArrayList<>();
Catalog catalog = new Catalog();
String id = UUID.randomUUID().toString();
catalog.setId(id);
catalog.setName("name1");
list.add(catalog);
catalog = new Catalog();
String id2 = UUID.randomUUID().toString();
catalog.setId(id2);
catalog.setName("name2");
catalog.setParentId(id);
list.add(catalog);
catalog = new Catalog();
String id3 = UUID.randomUUID().toString();
catalog.setId(id3);
catalog.setName("name3");
catalog.setParentId(id);
list.add(catalog);
catalog = new Catalog();
String id4 = UUID.randomUUID().toString();
catalog.setId(id4);
catalog.setName("name4");
catalog.setParentId(id);
list.add(catalog);
catalog = new Catalog();
String id5 = UUID.randomUUID().toString();
catalog.setId(id5);
catalog.setName("name5");
catalog.setParentId(id2);
list.add(catalog);
catalog = new Catalog();
String id6 = UUID.randomUUID().toString();
catalog.setId(id6);
catalog.setName("name6");
catalog.setParentId(id2);
list.add(catalog);
try {
List<Catalog> tree = getTree(list, "id");
System.out.println(JSON.toJSONString(tree));
} catch (Exception e) {
e.printStackTrace();
}
总结
好记性不如烂笔头!!!