把列表转换为树结构

/**
* 把列表转换为树结构
*
* @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;
}

测试实体类

/**
* 测试实体类
*/
public class Catalog { /**
* 唯一编号 uuid
*/
private String id; /**
* 名称
*/
private String name; /**
* 父节点id
*/
private String parentId; /**
* 子节点(数据库中不存在该字段,仅用于传输数据使用)
*/
private List<?> children; // 省略 get set
}

测试

/**
* 测试 一共有六个Catalog
* 其中:name1下面有三个子节点:name2、name3、name4
* name2下面有两个子节点:name5、name6
*/
@Test
public void ListToMap() throws Exception {
List<Catalog> list = new ArrayList<>(); Catalog catalog = new Catalog();
String flowId = randomUUID();
catalog.setFlowId(flowId);
catalog.setName("name1");
list.add(catalog); catalog = new Catalog();
String flowId2 = randomUUID();
catalog.setFlowId(flowId2);
catalog.setName("name2");
catalog.setParentId(flowId);
list.add(catalog); catalog = new Catalog();
String flowId3 = randomUUID();
catalog.setFlowId(flowId3);
catalog.setName("name3");
catalog.setParentId(flowId);
list.add(catalog); catalog = new Catalog();
String flowId4 = randomUUID();
catalog.setFlowId(flowId4);
catalog.setName("name4");
catalog.setParentId(flowId);
list.add(catalog); catalog = new Catalog();
String flowId5 = randomUUID();
catalog.setFlowId(flowId5);
catalog.setName("name5");
catalog.setParentId(flowId2);
list.add(catalog); catalog = new Catalog();
String flowId6 = randomUUID();
catalog.setFlowId(flowId6);
catalog.setName("name6");
catalog.setParentId(flowId2);
list.add(catalog); List<Catalog> tree = getTree(list, "flowId");
System.out.println(JSON.toJSONString(tree)); /* 装换后输出json样式
[
{
"id" : "ee55dafee60d44a3a143bd3623f29aa9",
"name" : "name1",
"children" : [
{
"id" : "2e049bdb67624054ad989b511f1b7674",
"parentId" : "ee55dafee60d44a3a143bd3623f29aa9",
"name" : "name2",
"children" : [
{
"id" : "9292a15c7a5e4983ac03d10c5fe12a14",
"name" : "name5",
"parentId" : "2e049bdb67624054ad989b511f1b7674"
},
{
"id" : "6cd9608726a1438682f239b6017680ca",
"name" : "name6",
"parentId" : "2e049bdb67624054ad989b511f1b7674"
}
]
},
{
"id" : "98e90c9e23e445f980c4116bd4c83233",
"name" : "name3",
"parentId" : "ee55dafee60d44a3a143bd3623f29aa9"
},
{
"id" : "5e67e73c6aef4eb19b63b4789dcc3486",
"name" : "name4",
"parentId" : "ee55dafee60d44a3a143bd3623f29aa9"
}
]
}
]
*/
} protected String randomUUID() {
return UUID.randomUUID().toString().replace("-", "");
}

Java将List<T>集合组装成树(Tree)树结构组装的更多相关文章

  1. Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍.内容包括:ConcurrentSkipListMap介绍ConcurrentSki ...

  2. Java-杂项:Java数组Array和集合List、Set、Map

    ylbtech-Java-杂项:Java数组Array和集合List.Set.Map 1.返回顶部 1. 之前一直分不清楚java中的array,list.同时对set,map,list的用法彻底迷糊 ...

  3. Java中如何克隆集合——ArrayList和HashSet深拷贝

    编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...

  4. Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList

    概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析, ...

  5. Java多线程系列--“JUC集合”03之 CopyOnWriteArraySet

    概要 本章是JUC系列中的CopyOnWriteArraySet篇.接下来,会先对CopyOnWriteArraySet进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解 ...

  6. Java多线程系列--“JUC集合”04之 ConcurrentHashMap

    概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...

  7. Java多线程系列--“JUC集合”06之 ConcurrentSkipListSet

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListSet类进行详细的介绍.内容包括:ConcurrentSkipListSet介绍ConcurrentSki ...

  8. Java多线程系列--“JUC集合”07之 ArrayBlockingQueue

    概要 本章对Java.util.concurrent包中的ArrayBlockingQueue类进行详细的介绍.内容包括:ArrayBlockingQueue介绍ArrayBlockingQueue原 ...

  9. Java多线程系列--“JUC集合”08之 LinkedBlockingQueue

    概要 本章介绍JUC包中的LinkedBlockingQueue.内容包括:LinkedBlockingQueue介绍LinkedBlockingQueue原理和数据结构LinkedBlockingQ ...

  10. Java多线程系列--“JUC集合”09之 LinkedBlockingDeque

    概要 本章介绍JUC包中的LinkedBlockingDeque.内容包括:LinkedBlockingDeque介绍LinkedBlockingDeque原理和数据结构LinkedBlockingD ...

随机推荐

  1. SOA面向服务架构——SOA的概念

    SOA的概念是Gartner 在1996年提出来的,并于2002年12月进一步提出SOA是“现代应用开发领域最重要的课题”.   一.SOA的定义 SOA分为广义的SOA和狭义的SOA,广义的SOA是 ...

  2. zookeeper for windows

    1,安装java环境,安装完java之后,添加用户变量.并在命令行中测试 java -version . 2,下载zookeeper http://mirrors.shu.edu.cn/apache/ ...

  3. 将项目发布到Maven中央仓库的不完整纪要

    背景 有几个Utils性质的Jar需要跨项目引用,原本想部署私有Maven仓库,后来感觉太麻烦,索性直接发布到中央库,引用时也方便. 发布成功之后,觉得某些细节还是有必要记录一下. 资源 Sonaty ...

  4. 【洛谷】【lca+结论】P3398 仓鼠找sugar

    [题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...

  5. C# winform webbrowser如何指定内核为IE11?

    1)假设你应用程序的名字为MyApplication.exe 2)运行Regedit,打开注册表,找到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsof ...

  6. 20155314 2016-2017-2 《Java程序设计》第9周学习总结

    20155314 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛型和自定义 ...

  7. Sequelize-nodejs-1-getting started

    Sequelize is a promise-based ORM for Node.js v4 and up. It supports the dialects PostgreSQL, MySQL, ...

  8. request请求转换成对象。

    1)前端post数据过来,key和val键值对会有很多,这个时候往后端进行插值的时候,最好将这些键值对转换成对象进行处理. 使用common-beanutils 来将前端传递过来的map直接转换成对象 ...

  9. ddt 接口示范以及报告生成html案例

    1.数据构造获取我就不写了直接以test_data=[  ] 构造一个简单数据建模.实际你从哪里获取根据情况excel也好yaml也罢 2.用例套件处理,报告生成处理 import ddtimport ...

  10. P1776 宝物筛选_NOI导刊2010提高(02)

    题目描述 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物.看来小FF只能含泪 ...