数据类似如下:

id			parent_id
a 				 0
b				 0
c				 a
d				 b

使用 TreeNode 保存树结构。

public class TreeNode extends Menu {
    public TreeNode(){}

    public TreeNode(String id){
        this.setId(id);
    }

	// 该方法是方便再树中保存节点的信息,可以直接用dao层的实体来初始化 treenode
    public TreeNode(Menu menu){
        if(menu != null){
            BeanUtils.copyProperties(menu, this);
        }
    }

	// 用来记录当前节点的父节点
    @JsonIgnore
    private String parent;

    private List<TreeNode> children = new ArrayList<>();
}
  • 用一个map保存所有的节点,需要时再取出。
  • TreeNode中添加一个parent字段用于判断是否有父节点,返回结果时可取消。

    @Override
    public List<TreeNode> buildTree(){
        List<Menu> nodeList = list();

        HashMap<String, TreeNode> treeNodeMap = new HashMap<>();
        HashMap<String, Menu> nodeMap = new HashMap<>();

        // 建立id-card映射关系
        nodeList.forEach((Menu menu)->{
            nodeMap.put(menu.getId(), menu);
        });

        for(Menu menu: nodeList){
            String parentID = menu.getPid();
            String sonID = menu.getId();

            TreeNode parentNode = null;
            TreeNode sonNode = null;

            if(! treeNodeMap.containsKey(parentID)){
                parentNode = new TreeNode(nodeMap.get(parentID));
                treeNodeMap.put(parentID, parentNode);
            }else{
                parentNode = treeNodeMap.get(parentID);
            }

            if(! treeNodeMap.containsKey(sonID)){
                sonNode = new TreeNode(nodeMap.get(sonID));
                treeNodeMap.put(sonID, sonNode);
            }else{
                sonNode = treeNodeMap.get(sonID);
            }

            parentNode.getChildren().add(sonNode);
            sonNode.setParent(parentID);
        }

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

        // 找到所有根节点
        for (Map.Entry<String, TreeNode> entry : treeNodeMap.entrySet()){
            if(entry.getValue().getParent() == null){
                res.add(entry.getValue());
            }
        }

		// res.get(0) 就是id为0的节点,他是所有节点的父节点
        return res.get(0).getChildren();
    }