树形结构数据是后台开发中非常常见的一种数据结构。后台管理系统中必要的一种结构,常见的树形结构数据有,部门树,权限树等等,利用该数据结构可以让你的系统数据展示一目了然,并且为分配这些数据也提供了极大地便利。如图所示的是菜单树。
菜单选择树:
这样的树通常看起来容易实现,但是实际生成有一定的难度,尤其是没有顶级节点时(一共n个节点,其中n-1个节点直接或者间接挂在一个节点上的情况),代码稍稍有点复杂。生成这样的一棵树,必须满足节点有id(节点唯一标识符),pid(父节点的唯一标识符)和子节点集合。用java类可以描述为:
@Data
public class TreeNode {
* 唯一标识符
private Long key;
* 节点描述
private String title;
* 父节点唯一标识符
private Long parentId;
* 子节点集合
private List<TreeNode> children;
注意: 其中的@Data是Lombok提供的注解,提供了字段的get、set、equals、hashCode、canEqual、toString等方法的生成。如果不了解的同学,自行百度。
如果不漏掉所有的节点,需要先找出所有的父节点
public class Tree {
List<TreeNode> nodes;
public Tree(List<TreeNode> nodes) {
this.nodes = nodes;
* 构建树形结构
public List<TreeNode> buildTree() {
List<TreeNode> treeNodes = new ArrayList<>();
List<TreeNode> rootNodes = getRootNodes();
for (TreeNode rootNode : rootNodes) {
buildChildNodes(rootNode);
treeNodes.add(rootNode);
return treeNodes;
* 递归子节点
private void buildChildNodes(TreeNode node) {
List<TreeNode> children = getChildNodes(node);
if (!children.isEmpty()) {
for (TreeNode child : children) {
buildChildNodes(child);
node.setChildren(children);
* 获取父节点下所有的子节点
public List<TreeNode> getChildNodes(TreeNode pNode) {
List<TreeNode> childNodes = new ArrayList<>();
for (TreeNode n : nodes) {
if (pNode.getKey().equals(n.getParentId())) {
childNodes.add(n);
return childNodes;
* 判断是否为根节点
public boolean rootNode(TreeNode node) {
boolean isRootNode = true;
for (TreeNode n : nodes) {
if (node.getParentId().equals(n.getKey())) {
isRootNode = false;
break;
return isRootNode;
* 获取集合中所有的根节点
public List<TreeNode> getRootNodes() {
List<TreeNode> rootNodes = new ArrayList<>();
for (TreeNode n : nodes) {
if (rootNode(n)) {
rootNodes.add(n);
return rootNodes;
从上面代码中可以看到,主要有两个重要的步骤,一、获取集合中的所有的根节点;二、递归子节点。
不难看出该类只有一个构造器,并且构造的时候需要传入节点集合。
public class Test {
public static void main(String[] args) {
List<TreeNode> list = new ArrayList<>();
Tree tree = new Tree(list);
List<TreeNode> treeNodes = tree.buildTree();
通常这个生成之后,数据就可以交由前端去渲染。可供常见的前端框架antd,iview等使用,具体情况具体修改。生成已经有了,但是如果只有子节点,如果完整渲染出仅包含该子节点的树呢?其实思路也是和这个类似的
Hutool是一个小而全的 Java 工具类库,通过静态方法封装,降低相关 API 的学习成本,提高工作效率,使 Java 拥有函数式语言般的优雅。
构建菜单树是我们常用的功能,构建树的时候就考虑,能不能写一个公共的类,用来构建树,思索了许久,没...
递归实现树结构数据
一、递归概念:自己的理解,自己调用自己,何为自己钓鱼呢自己,比如
下面的**chilMenus.add(buildChilTree(menuNode))**就是在自己调用自己,查询到下一级的下一级,有几级我就调用几次我自己,从而实现树状结构中的父节点下的所有子级。
//递归,建立子树形结构
public Menu buildChilTree(Menu pNode){
List<Menu> chilMenus =new ArrayList<Menu>();
2.造一些数据
注意:根节点的pid=0,其他节点的pid跟id是有对应的父子关系的。这里只展示递归生成树的代码,查询数据库的操作非常简单,只用到了一句sql,然后将结果封装成List。
service代码:
返回数据格式如下:...
@TableName("流域单元")
@ApiModel(value = "流域单元", description = "流域单元")
public class WaterCode implements Serializable {
@TableField(value = "PID")
@ApiModelProperty(va
// 构建node列表(数据源)
List<TreeNode<String>> nodeList = CollUtil.newArrayList();
nodeList.add(new TreeNode<>("1", "0", "系统管理", 5));
nodeList.add(new TreeNode<..