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

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


将服务器后台返回的数据转换为树结构数据给前台_第1张图片

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

将服务器后台返回的数据转换为树结构数据给前台_第2张图片

接下来我们就来写个例子测试一下:一般我们采用两种方式来转换为树: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 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 getChildren() {
        return children;
    }

    public void setChildren(List 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 bulid(List treeNodes) {

        List trees = new ArrayList();

        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.getChildren().add(it);
                }
            }
        }
        return trees;
    }

    /**
     * 使用递归方法建树
     * @param treeNodes
     * @return
     */
    public static List buildByRecursive(List treeNodes) {
        List trees = new ArrayList();
        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 treeNodes) {
        for (TreeNode it : treeNodes) {
            if(treeNode.getId().equals(it.getParentId())) {
            if (treeNode.getChildren() == null) {
                treeNode.setChildren(new ArrayList());
            }
            //是否还有子节点,如果有的话继续往下遍历,如果没有则直接返回
            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 list = new ArrayList();

        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 trees = TreeBuilder.bulid(list);

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

    }

}

 
  

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

将服务器后台返回的数据转换为树结构数据给前台_第3张图片

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

将服务器后台返回的数据转换为树结构数据给前台_第4张图片

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

将服务器后台返回的数据转换为树结构数据给前台_第5张图片

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


将服务器后台返回的数据转换为树结构数据给前台_第6张图片


你可能感兴趣的:(数据结构)