在项目中难免会用到树形结构,毕竟这是一种常用的组织架构。楼主这里整理了两个实现的版本,可以直接拿来使用,非常方便。

楼主没有单独建项目,直接在以前的一个Demo上实现的。第一种,看下面代码:

package com.johanChan.WebSocket.utils;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
//图层结构
public class TreeBuilder {
    List<Node> nodes = new ArrayList<>();
    public String buildTree(List<Node> nodes) {
        TreeBuilder treeBuilder = new TreeBuilder(nodes);
        return treeBuilder.buildJSONTree();
    public TreeBuilder() {}
    public TreeBuilder(List<Node> nodes) {
        super();
        this.nodes = nodes;
    // 构建JSON树形结构
    public String buildJSONTree() {
        List<Node> nodeTree = buildTree();
        String jsonStr = JSON.toJSONString(nodeTree);
        return jsonStr;
    // 构建树形结构
    public List<Node> buildTree() {
        List<Node> treeNodes = new ArrayList<>();
        List<Node> rootNodes = getRootNodes();
        for (Node rootNode : rootNodes) {
            buildChildNodes(rootNode);
            treeNodes.add(rootNode);
        return treeNodes;
    // 递归子节点
    public void buildChildNodes(Node node) {
        List<Node> children = getChildNodes(node);
        if (!children.isEmpty()) {
            for (Node child : children) {
                buildChildNodes(child);
            node.setChildren(children);
    // 获取父节点下所有的子节点
    public List<Node> getChildNodes(Node pnode) {
        List<Node> childNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (pnode.getId().equals(n.getParentId())) {
                childNodes.add(n);
        return childNodes;
    // 判断是否为根节点
    public boolean rootNode(Node node) {
        boolean isRootNode = true;
        for (Node n : nodes) {
            if (node.getParentId().equals(n.getId())) {
                isRootNode = false;
                break;
        return isRootNode;
    // 获取集合中所有的根节点
    public List<Node> getRootNodes() {
        List<Node> rootNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (rootNode(n)) {
                rootNodes.add(n);
        return rootNodes;
    public static class Node {
        private Integer id;
        private Integer parentId;
        private String name;
        private String code;
        private Integer level;
        private List<Node> children;
        public Node() {}
        public Node(Integer id,Integer parentId,String name,String code,Integer level){
            super();
            this.id = id;
            this.parentId = parentId;
            this.name = name;
            this.code = code;
            this.level = level;
        public Integer getId() {
            return id;
        public void setId(Integer id) {
            this.id = id;
        public Integer getParentId() {
            return parentId;
        public void setParentId(Integer parentId) {
            this.parentId = parentId;
        public String getName() {
            return name;
        public void setName(String name) {
            this.name = name;
        public String getCode() {
            return code;
        public void setCode(String code) {
            this.code = code;
        public Integer getLevel() {
            return level;
        public void setLevel(Integer level) {
            this.level = level;
        public List<Node> getChildren() {
            return children;
        public void setChildren(List<Node> children) {
            this.children = children;

  看起来很长对吗?没关系,直接copy一下就可以使用。首先生成一个树形结构的数据:

    public static List<TreeBuilder.Node> buildNode(){
        List<TreeBuilder.Node> nodeList = new ArrayList<>();
        TreeBuilder.Node node = new TreeBuilder.Node(0,-1,"地球","WORD",1);
        TreeBuilder.Node node1 = new TreeBuilder.Node(1,0,"中国","CHN",1);
        TreeBuilder.Node node2 = new TreeBuilder.Node(2,1,"华北区域","A",2);
        TreeBuilder.Node node3 = new TreeBuilder.Node(3,1,"华南区域","B",2);
        TreeBuilder.Node node4 = new TreeBuilder.Node(4,1,"华东区域","C",2);
        TreeBuilder.Node node5 = new TreeBuilder.Node(5,1,"华西区域","D",2);
        TreeBuilder.Node node6 = new TreeBuilder.Node(6,1,"华中区域","E",2);
        TreeBuilder.Node node7 = new TreeBuilder.Node(7,6,"河南","豫",3);
        TreeBuilder.Node node8 = new TreeBuilder.Node(8,6,"湖北","鄂",3);
        TreeBuilder.Node node9 = new TreeBuilder.Node(9,6,"湖南","湘",3);
        TreeBuilder.Node node10 = new TreeBuilder.Node(10,6,"江西","赣",3);
        TreeBuilder.Node node11 = new TreeBuilder.Node(11,7,"郑州","豫A",4);
        TreeBuilder.Node node12 = new TreeBuilder.Node(12,7,"开封","豫B",4);
        TreeBuilder.Node node13 = new TreeBuilder.Node(13,7,"洛阳","豫C",4);
        TreeBuilder.Node node14 = new TreeBuilder.Node(14,7,"南阳","豫R",4);
        TreeBuilder.Node node15 = new TreeBuilder.Node(15,11,"金水区","豫A-1",5);
        nodeList.add(node);
        nodeList.add(node1);nodeList.add(node2);nodeList.add(node3);
        nodeList.add(node4);nodeList.add(node5);nodeList.add(node6);
        nodeList.add(node7);nodeList.add(node8);nodeList.add(node9);
        nodeList.add(node10);nodeList.add(node11);nodeList.add(node12);
        nodeList.add(node13);nodeList.add(node14);nodeList.add(node15);
        return nodeList;

  然后调用new TreeBuilder().buildTree(nodeList)就可以返回json格式的字符串了:

package com.johanChan.WebSocket.controller;
import com.alibaba.fastjson.JSON;
import com.johanChan.WebSocket.utils.CommonUtils;
import com.johanChan.WebSocket.utils.TreeBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class TreeController {
    List<TreeBuilder.Node> nodeList ;
        nodeList = CommonUtils.buildNode();
    @ResponseBody
    @RequestMapping("/getTreeJson")
    public String getTreeJson() {
//        List<TreeBuilder.Node> nodeList = CommonUtils.buildNode();
        String result = new TreeBuilder().buildTree(nodeList);
     return result;
    }
  }

  启动项目,访问/getTreeJson可以看到,页面返回了json字符串:

   整理后如下:

"children":[ "children":[ "code":"A", "id":2, "level":2, "name":"华北区域", "parentId":1 "code":"B", "id":3, "level":2, "name":"华南区域", "parentId":1 "code":"C", "id":4, "level":2, "name":"华东区域", "parentId":1 "code":"D", "id":5, "level":2, "name":"华西区域", "parentId":1 "children":[ "children":[ "children":[ "code":"豫A-1", "id":15, "level":5, "name":"金水区", "parentId":11 "code":"豫A", "id":11, "level":4, "name":"郑州", "parentId":7 "code":"豫B", "id":12, "level":4, "name":"开封", "parentId":7 "code":"豫C", "id":13, "level":4, "name":"洛阳", "parentId":7 "code":"豫R", "id":14, "level":4, "name":"南阳", "parentId":7 "code":"豫", "id":7, "level":3, "name":"河南", "parentId":6 "code":"鄂", "id":8, "level":3, "name":"湖北", "parentId":6 "code":"湘", "id":9, "level":3, "name":"湖南", "parentId":6 "code":"赣", "id":10, "level":3, "name":"江西", "parentId":6 "code":"E", "id":6, "level":2, "name":"华中区域", "parentId":1 "code":"CHN", "id":1, "level":1, "name":"中国", "parentId":0 "code":"WORD", "id":0, "level":1, "name":"地球", "parentId":-1

  第一种方法完成,下面是第二种实现,首先建立一个类:

package com.johanChan.WebSocket.utils;

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

public class Tree<T> {
/**
* 节点ID
*/
private Integer id;
/**
* 显示节点文本
*/
private String text;
/**
* 父ID
*/
private Integer parentId;

private Integer level;
/**
* 节点的子节点
*/
// private List<Tree<T>> nodes = new ArrayList<Tree<T>>();
private List<Tree<T>> nodes = null;

public Tree() {}
public Tree(Integer id,Integer parentId,String text,Integer level){
super();
this.id = id;
this.text = text;
this.parentId = parentId;
this.level = level;
}

public Integer getId() {
return id;
}

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

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public Integer getParentId() {
return parentId;
}

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

public Integer getLevel() {
return level;
}

public void setLevel(Integer level) {
this.level = level;
}

public List<Tree<T>> getNodes() {
if(nodes==null){
nodes = new ArrayList<Tree<T>>();
}
return nodes;
}

public void setNodes(List<Tree<T>> nodes) {
this.nodes = nodes;
}


}

  然后对Tree进行排序:

package com.johanChan.WebSocket.utils;
import java.util.ArrayList;
import java.util.List;
public class BuildTree {
    public static <T> List<Tree<T>> build(List<Tree<T>> nodes) {
        if (nodes == null) {
            return null;
        List<Tree<T>> topNodes = new ArrayList<>();
        for (Tree<T> children : nodes) {
            String pid = children.getParentId();
            if (pid.equals(children.getId() )) {
                topNodes.add(children);
                continue;
            for (Tree<T> parent : nodes) {
                String id = parent.getId();
                if (id != null && id.equals(pid)) {
                    parent.getNodes().add(children);
        return topNodes;

  然后生成数据:

public static List<Tree<TreeBuilder.Node>> buildTree(){
        List<Tree<TreeBuilder.Node>> treeList = new ArrayList<>();
        Tree<TreeBuilder.Node> tree = new Tree<TreeBuilder.Node>(0,0,"地球",1);
        Tree tree1 = new Tree(1,0,"中国",1);
        Tree tree2 = new Tree(2,1,"华北区域",2);
        Tree tree3 = new Tree(3,1,"华南区域",2);
        Tree tree4 = new Tree(4,1,"华东区域",2);
        Tree tree5 = new Tree(5,1,"华西区域",2);
        Tree tree6 = new Tree(6,1,"华中区域",2);
        Tree tree7 = new Tree(7,6,"河南",3);
        Tree tree8 = new Tree(8,6,"湖北",3);
        Tree tree9 = new Tree(9,6,"湖南",3);
        Tree tree10 = new Tree(10,6,"江西",3);
        Tree tree11 = new Tree(11,7,"郑州",4);
        Tree tree12 = new Tree(12,7,"开封",4);
        Tree tree13 = new Tree(13,7,"洛阳",4);
        Tree tree14 = new Tree(14,7,"南阳",4);
        Tree tree15 = new Tree(15,11,"金水区",5);
        treeList.add(tree);
        treeList.add(tree1);treeList.add(tree2);treeList.add(tree3);
        treeList.add(tree4);treeList.add(tree5);treeList.add(tree6);
        treeList.add(tree7);treeList.add(tree8);treeList.add(tree9);
        treeList.add(tree10);treeList.add(tree11);treeList.add(tree12);
        treeList.add(tree13);treeList.add(tree14);treeList.add(tree15);
        return treeList;

  调用方法:

package com.johanChan.WebSocket.controller;
import com.alibaba.fastjson.JSON;
import com.johanChan.WebSocket.utils.BuildTree;
import com.johanChan.WebSocket.utils.CommonUtils;
import com.johanChan.WebSocket.utils.Tree;
import com.johanChan.WebSocket.utils.TreeBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class TreeController {
    List<TreeBuilder.Node> nodeList ;
    List<Tree<TreeBuilder.Node>> treeList;
        nodeList = CommonUtils.buildNode();
        treeList = CommonUtils.buildTree();
    @ResponseBody
    @RequestMapping("/getTreeJson")
    public String getTreeJson() {
//        List<TreeBuilder.Node> nodeList = CommonUtils.buildNode();
//        String result = CommonUtils.buildTree(nodeList);
        List<Tree<TreeBuilder.Node>> resultList = BuildTree.build(treeList);
        String result = JSON.toJSONString(resultList);
        return result;

  返回数据如下:

"id":0, "level":1, "nodes":[ "id":1, "level":1, "nodes":[ "id":2, "level":2, "nodes":[ "parentId":1, "text":"华北区域" "id":3, "level":2, "nodes":[ "parentId":1, "text":"华南区域" "id":4, "level":2, "nodes":[ "parentId":1, "text":"华东区域" "id":5, "level":2, "nodes":[ "parentId":1, "text":"华西区域" "id":6, "level":2, "nodes":[ "id":7, "level":3, "nodes":[ "id":11, "level":4, "nodes":[ "id":15, "level":5, "nodes":[ "parentId":11, "text":"金水区" "parentId":7, "text":"郑州" "id":12, "level":4, "nodes":[ "parentId":7, "text":"开封" "id":13, "level":4, "nodes":[ "parentId":7, "text":"洛阳" "id":14, "level":4, "nodes":[ "parentId":7, "text":"南阳" "parentId":6, "text":"河南" "id":8, "level":3, "nodes":[ "parentId":6, "text":"湖北" "id":9, "level":3, "nodes":[ "parentId":6, "text":"湖南" "id":10, "level":3, "nodes":[ "parentId":6, "text":"江西" "parentId":1, "text":"华中区域" "parentId":0, "text":"中国" "parentId":0, "text":"地球" View Code

  OK!以上两种方法都比较有通用性,把自己的数据整理后调用就可以了。