最近遇到一个需要构造树形结构的需求,就是提供给类似zTree组件的后端接口 ,在网上找到一种实现方式,但是博主的实现方式(https://blog.csdn.net/aeaiesb/article/details/40783361),实体类都是Node,我们真实需求中实体类的属性不一定都和博主的相同,那么能不能改造一下呢?下面是改造后的结果。
所有要实现树形结构的实体类继承NodeHelper类
/**
* @Author: gu
* @Date: 2019-09-24 20:54
* @Desc: 树形结构基类
*/
@Data
public class NodeHelper {
public Integer id;
public Integer parentId;
public List extends NodeHelper> child;
}
import com.alibaba.fastjson.JSON;
import com.alibaba.model.base.NodeHelper;
import com.alibaba.test.model.NodeTestVo;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: gu
* @Date: 2019-09-24 19:42
* @Desc: 树形数据构造器
*/
public class TreeBuilder {
List extends NodeHelper> nodes = new ArrayList<>();
public TreeBuilder(List extends NodeHelper> nodes) {
super();
this.nodes = nodes;
}
public static void main(String[] args) {
List nodes = new ArrayList<>();
NodeTestVo p1 = new NodeTestVo(1, 0, "1", "");
NodeTestVo p6 = new NodeTestVo(2, 0, "2", "");
NodeTestVo p7 = new NodeTestVo(201, 2, "201", "");
NodeTestVo p2 = new NodeTestVo(101, 1, "101", "");
NodeTestVo p3 = new NodeTestVo(102, 1, "102", "");
NodeTestVo p4 = new NodeTestVo(10101, 101, "10101", "");
NodeTestVo p5 = new NodeTestVo(10102, 101, "10102", "");
nodes.add(p1);
nodes.add(p2);
nodes.add(p3);
nodes.add(p4);
nodes.add(p5);
nodes.add(p6);
nodes.add(p7);
TreeBuilder treeBuilder = new TreeBuilder(nodes);
List nodeVos = treeBuilder.buildTree();
System.out.println(JSON.toJSONString(nodeVos));
}
/**
* 构建树形结构
*
* @return
*/
public List buildTree() {
List treeNodes = new ArrayList<>();
List rootNodes = getRootNodes();
for (NodeHelper rootNode : rootNodes) {
buildChildNodes(rootNode);
treeNodes.add(rootNode);
}
return treeNodes;
}
/**
* 递归子节点
*
* @param node
*/
public void buildChildNodes(NodeHelper node) {
List children = getChildNodes(node);
if (!children.isEmpty()) {
for (NodeHelper child : children) {
buildChildNodes(child);
}
node.setChild(children);
}
}
/**
* 获取父节点下所有的子节点
*
* @param pnode
* @return
*/
public List getChildNodes(NodeHelper pnode) {
List childNodes = new ArrayList<>();
for (NodeHelper n : nodes) {
if (pnode.getId().equals(n.getParentId())) {
childNodes.add(n);
}
}
return childNodes;
}
/**
* 判断是否为根节点
*
* @param node
* @return
*/
public boolean rootNode(NodeHelper node) {
boolean isRootNode = true;
for (NodeHelper n : nodes) {
if (node.getParentId().equals(n.getId())) {
isRootNode = false;
break;
}
}
return isRootNode;
}
/**
* 获取集合中所有的根节点
*
* @return
*/
public List getRootNodes() {
List rootNodes = new ArrayList<>();
for (NodeHelper n : nodes) {
if (rootNode(n)) {
rootNodes.add(n);
}
}
return rootNodes;
}
}
测试用实体类:
/**
* @Author: gu
* @Date: 2019-09-24 21:05
* @Desc: 树形结构测试类
*/
@Data
public class NodeTestVo extends NodeHelper {
private String text;
private String url;
public NodeTestVo(Integer id, Integer parentId, String text, String url) {
super();
this.id = id;
this.parentId = parentId;
this.text = text;
this.url = url;
}
}
测试结果:
[
{
"child": [
{
"child": [
{
"id": 10101,
"parentId": 101,
"text": "10101",
"url": ""
},
{
"id": 10102,
"parentId": 101,
"text": "10102",
"url": ""
}
],
"id": 101,
"parentId": 1,
"text": "101",
"url": ""
},
{
"id": 102,
"parentId": 1,
"text": "102",
"url": ""
}
],
"id": 1,
"parentId": 0,
"text": "1",
"url": ""
},
{
"child": [
{
"id": 201,
"parentId": 2,
"text": "201",
"url": ""
}
],
"id": 2,
"parentId": 0,
"text": "2",
"url": ""
}
]
Refer:https://blog.csdn.net/aeaiesb/article/details/40783361