java代码怎样查出树形结构的某个节点的所有子孙节点?要算法实现!!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java代码怎样查出树形结构的某个节点的所有子孙节点?要算法实现!!相关的知识,希望对你有一定的参考价值。

ID PID
1 0
2 0
3 1
4 1
5 1
6 2
7 6

参考技术A 这样的用简单的判断就行了 :先判断PID为空的,这个是父节点,然后取出PID为空的Id当做取其子节点的父节点,一次判断就行了,结合列子:取PID为空的ID即1,2,然后把取PId等于1和2的ID即345和6然后分别挂在1和2下,345就是1的子节点,6是2的子节点,有多节点的一次类推(这只是其中一个简单的方法)
追问

java代码怎么实现,这有三个子菜单!!!

参考技术B 递归。追问

我在jsp写的方法, 不知道怎么写条件还有怎样显示出来

MySQL查询父节点下面的所有子孙节点,查询用户列表时多级(公司)部门处理,根据反射,递归树形结构工具类

MySQL查询父节点下面的所有子孙节点

-- 获取某个菜单的所有子孙节点同理

SELECT id,dept_name,parent_id
FROM
		(SELECT id,parent_id,dept_name FROM sys_dept where parent_id > 0 ORDER BY parent_id, sort) a,
		(SELECT @pv :=1) b
WHERE (FIND_IN_SET(parent_id,@pv)>0 And @pv := concat(@pv, ',', id))

执行结果:

查询用户列表时多级(公司)部门处理

SELECT a.id,a.user_name,a.real_name,a.phone_number,a.dept_id,a.status,b.parent_id,b.dept_name, 
		if(c.parent_id = 0,null,c.dept_name) parentName,
		if(c.parent_id = 0,c.dept_name,(SELECT dept_name FROM sys_dept d WHERE c.parent_id=d.id))  comName
FROM sys_user a
LEFT JOIN sys_dept b on a.dept_id=b.id
LEFT JOIN sys_dept c on b.parent_id=c.id

执行结果:

根据反射,递归树形结构工具类

import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * 构建树结构工具类
 * @author Admin
 */
public class TreeUtil 

	/**
     * 获取前端所需树结构
     */
    public static<T> List<T> buildTree(List<T> list) 
        //获取根节点
        List<T> root = buildTree(list, 0L);
        getChild(root, list);
        return root;
    
    
    private static<T> List<T> buildTree(List<T> dataList,Long pid)
        List<T> list= new ArrayList<>();
        Iterator<T> it = dataList.iterator();
        while (it.hasNext()) 
            T t = it.next();
            Long parentId = (Long)getFieldValue(t,"parentId");
            if (parentId.intValue()==pid.intValue()) 
                list.add(t);
                it.remove();
            
        
        return list;
    
    
    /**
     * 递归子节点
     */
    private static<T> void getChild(List<T> root,List<T> list)
        try 
            for (T nav : root) 
                Long id = (Long)getFieldValue(nav,"id");
                List<T> childList = buildTree(list, id);
				getChild(childList, list);
				//这里要注意,获取实体类的children属性时,要将 children 设置成public,如果时private会报错。
                Field child = ReflectUtil.getField(nav.getClass(), "children");
                child.set(nav,childList);
            
        catch (Exception e)
            e.printStackTrace();
        
    

    private static<T> Object getFieldValue(T t,String fieldName)
        Field field = ReflectUtil.getField(t.getClass(), fieldName);
        return ReflectUtil.getFieldValue(t, field);
    


使用:

@Data
public class SysMenu 

    @ApiModelProperty(value = "id")
    @TableId(type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "父菜单ID")
    @TableField("parent_id")
    private Long parentId;

    @ApiModelProperty(value = "菜单名称")
    @TableField("name")
    private String name;
	
	//...
    //省略其他属性
    //...

	//这里要将 children 设置成public,否则在 TreeUtil 通过反射获取字段时无法获取,会报错
    @ApiModelProperty(value = "子菜单")
    public transient List<SysMenu> children = new ArrayList<>();


/**
 * TreeVo树结构实体类
 * @author Admin
 */
@Data
public class TreeVo implements Serializable 
    private static final long serialVersionUID = 1L;

    /** 节点ID */
    private Long id;

    /** 节点名称 */
    private String label;

    /** 父级id */
    private Long parentId;

    /** 子节点 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<TreeVo> children;

    public TreeVo()  

    public TreeVo(SysDept dept) 
        this.id = dept.getId();
        this.label = dept.getName();
        this.parentId = dept.getParentId();
        this.children = dept.getChildren().stream().map(TreeVo::new).collect(Collectors.toList());
    

    public TreeVo(SysMenu menu) 
        this.id = menu.getId();
        this.label = menu.getName();
        this.parentId = menu.getParentId();
        this.children = menu.getChildren().stream().map(TreeVo::new).collect(Collectors.toList());
    


@GetMapping("/treeMenuList")
public ResultVo treeMenuList() 
    List<SysMenu> list= sysMenuService.list();
    List<SysMenu> trees = TreeUtil.buildTree(list);
    return ResultUtil.success(trees.stream().map(TreeVo::new).collect(Collectors.toList()));

效果:

以上是关于java代码怎样查出树形结构的某个节点的所有子孙节点?要算法实现!!的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询父节点下面的所有子孙节点,查询用户列表时多级(公司)部门处理,根据反射,递归树形结构工具类

MYSQL 查询树形结构数据,查询某个节点下的所有子节点数据。

树结构中查找子孙节点方法

树形结构数据还原成普通list,根据父类id获得所有子孙后代id集合方法实现

树形结构数据还原成普通list,根据父类id获得所有子孙后代id集合方法实现

MongoDB树形数据存储