您的位置:首页 > 其它

将服务器后台返回的数据转换为树结构数据给前台

2018-07-06 15:35 489 查看

       我们在前台向后台请求数据时可能会希望能得到一个树结构的数据结构,方便我们前台获取和使用,也能使得数据结构清晰,一目了然,树结构一般情况在我遇到的项目中都是某个表的自关联,使用到子父节点的关系,我们一般情况下可能会有这样的需求,获取全部数据或根据父节点获取子节点所有数据,如果我们直接返回数据,会让数据显得很乱,没有层次关系,所以我们需要使用树结构,我们先看一张图了解一下树结构:我这里随便找一张图了解一下即可



我们再看一张自关联的数据库表,最常见的就是地区表的自连接,例如深圳下面有南山区,广州下面有天河区


接下来我们就来写个例子测试一下:一般我们采用两种方式来转换为树:1.循环 2.递归

/**
* @Auther: HeJD
* @Date: 2018/7/6 14:43
* @Description:
*/

import java.util.List;

/**
* Created by Massive on 2016/12/26.
*/
public class TreeNode {

private String id;

private String parentId;

private String name;

private List<TreeNode> children;

public TreeNode(String id, String name, String parentId) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
public TreeNode(String id, String name, TreeNode parent) {
this.id = id;
this.parentId = parent.getId();
this.name = name;
}

public String getParentId() {
return parentId;
}

public void setParentId(String parentId) {
this.parentId = parentId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public List<TreeNode> getChildren() {
return children;
}

public void setChildren(List<TreeNode> children) {
this.children = children;
}

@Override
public String toString() {
return "TreeNode{" +
"id='" + id + '\'' +
", parentId='" + parentId + '\'' +
", name='" + name + '\'' +
", children=" + children +
'}';
}

}
/**
* @Auther: HeJD
* @Date: 2018/7/6 14:44
* @Description:
*/

import java.util.ArrayList;
import java.util.List;

/**
* Created by Massive on 2016/12/26.
*/
public class TreeBuilder {

/**
* 两层循环实现建树
* @param treeNodes 传入的树节点列表
* @return
*/
public static List<TreeNode> bulid(List<TreeNode> treeNodes) {

List<TreeNode> trees = new ArrayList<TreeNode>();

for (TreeNode treeNode : treeNodes) {

if ("0".equals(treeNode.getParentId())) {
trees.add(treeNode);
}

for (TreeNode it : treeNodes) {
if (it.getParentId() == treeNode.getId()) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<TreeNode>());
}
treeNode.getChildren().add(it);
}
}
}
return trees;
}

/**
* 使用递归方法建树
* @param treeNodes
* @return
*/
public static List<TreeNode> buildByRecursive(List<TreeNode> treeNodes) {
List<TreeNode> trees = new ArrayList<TreeNode>();
for (TreeNode treeNode : treeNodes) {
if ("0".equals(treeNode.getParentId())) {
trees.add(findChildren(treeNode,treeNodes));
}
}
return trees;
}

/**
* 递归查找子节点
* @param treeNodes
* @return
*/
public static TreeNode findChildren(TreeNode treeNode,List<TreeNode> treeNodes) {
for (TreeNode it : treeNodes) {
if(treeNode.getId().equals(it.getParentId())) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<TreeNode>());
}
//是否还有子节点,如果有的话继续往下遍历,如果没有则直接返回
treeNode.getChildren().add(findChildren(it,treeNodes));

}
}
return treeNode;
}

public static void main(String[] args) {

TreeNode treeNode1 = new TreeNode("1","广州","0");
TreeNode treeNode2 = new TreeNode("2","深圳","0");

TreeNode treeNode3 = new TreeNode("3","天河区",treeNode1);
TreeNode treeNode4 = new TreeNode("4","越秀区",treeNode1);
TreeNode treeNode5 = new TreeNode("5","黄埔区",treeNode1);
TreeNode treeNode6 = new TreeNode("6","石牌",treeNode3);
TreeNode treeNode7 = new TreeNode("7","百脑汇",treeNode6);

TreeNode treeNode8 = new TreeNode("8","南山区",treeNode2);
TreeNode treeNode9 = new TreeNode("9","宝安区",treeNode2);
TreeNode treeNode10 = new TreeNode("10","科技园",treeNode8);

List<TreeNode> list = new ArrayList<TreeNode>();

list.add(treeNode1);
list.add(treeNode2);
list.add(treeNode3);
list.add(treeNode4);
list.add(treeNode5);
list.add(treeNode6);
list.add(treeNode7);
list.add(treeNode8);
list.add(treeNode9);
list.add(treeNode10);

//第一种方式
List<TreeNode> trees = TreeBuilder.bulid(list);

//第二种方式
List<TreeNode> trees_ = TreeBuilder.buildByRecursive(list);

}

}
具体的执行逻辑和执行过程,可以将程序复制下来打断点一步一步执行,这样就可知道循环和递归分别是如何实现数据变成树结构的,下面贴一张我调试的数据内容,执行上面任何一种方法后的数据都是一样的。


循环的逻辑是这样的,假设第一个循环到的数据是广州:先查询广州下面所有的子节点并添加进来,所以第一遍就变成了


然后接着第二遍循环,假设第二遍循环到的数据是天河(当然也可能是其他的),那么逻辑就如下图,接着上面


递归的逻辑是,假设第一个循环到的数据是广州,那么就递归遍历所有广州下面的子节点,大概的流程图如下




阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐