Java递归实现树结构(包含Java 8 方法)

递归实现树结构数据

一、递归概念:自己的理解,自己调用自己,何为自己调用自己,比如
下面的**chilMenus.add(buildChilTree(menuNode))**就是在自己调用自己,查询到下一级的下一级,有几级我就调用几次我自己,从而实现树状结构中的父节点下的所有子级。

注:后面有 JDK 8 的写法,如果有涉及到模糊匹配,建议前端匹配,后端处理麻烦且做不到完美,不建议后端处理。

//递归,建立子树形结构
	public Menu buildChilTree(Menu pNode){
		List<Menu> chilMenus =new  ArrayList<Menu>();
		for(Menu menuNode : menuList) {
			if(menuNode.getParentId().equals(pNode.getId())) {
				chilMenus.add(buildChilTree(menuNode));
			}
		}
		pNode.setChildren(chilMenus);
		return pNode;
	}

那么,上代码:
①实体类

package recursion;

import java.util.List;
public class Menu {
	private String id;
	private String parentId;
	private String text;
	private String url;
	private String yxbz;
	private List<Menu> children;

	public Menu(String id,String parentId,String text,String url,String yxbz) {
		this.id=id;
		this.parentId=parentId;
		this.text=text;
		this.url=url;
		this.yxbz=yxbz;
	}

	public String getId() {
		return id;
	}

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

	public String getParentId() {
		return parentId;
	}

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

	public String getText() {
		return text;
	}

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

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getYxbz() {
		return yxbz;
	}

	public void setYxbz(String yxbz) {
		this.yxbz = yxbz;
	}

	public List<Menu> getChildren() {
		return children;
	}

	public void setChildren(List<Menu> children) {
		this.children = children;
	}

	@Override
	public String toString() {
		return "Menu{" +
				"id='" + id + '\'' +
				", parentId='" + parentId + '\'' +
				", text='" + text + '\'' +
				", url='" + url + '\'' +
				", yxbz='" + yxbz + '\'' +
				", children=" + children +
				'}';
	}
}

② getRootNode()获取根节点(父节点),buildChilTree(获取所有子节点),builTree整合子节点和父节点的数据,实现树结构

package recursion;

import java.util.ArrayList;
import java.util.List;
public class MenuTree{
	private List<Menu> menuList = new ArrayList<Menu>();
	public MenuTree(List<Menu> menuList) {
		this.menuList=menuList;
	}

	//建立树形结构
	public List<Menu> builTree(){
		List<Menu> treeMenus =new  ArrayList<Menu>();
		for(Menu menuNode : getRootNode()) {
			menuNode=buildChilTree(menuNode);
			treeMenus.add(menuNode);
		}
		return treeMenus;
	}

	//递归,建立子树形结构
	public Menu buildChilTree(Menu pNode){
		List<Menu> chilMenus =new  ArrayList<Menu>();
		for(Menu menuNode : menuList) {
			if(menuNode.getParentId().equals(pNode.getId())) {
				chilMenus.add(buildChilTree(menuNode));
			}
		}
		pNode.setChildren(chilMenus);
		return pNode;
	}

	//获取根节点(获取所有的父节点)
	public List<Menu> getRootNode() {
		List<Menu> rootMenuLists =new  ArrayList<Menu>();
		for(Menu menuNode : menuList) {
			if(menuNode.getParentId().equals("0")) {
				rootMenuLists.add(menuNode);
			}
		}
		return rootMenuLists;
	}
}

③ 测试类

package recursion;

import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;
public class Recursion {
	public static void main(String[] args) {
		List<Menu> menuList= new ArrayList<Menu>();
		/*插入一些数据*/
		menuList.add(new Menu("GN001D000","0","系统管理","/admin","Y"));
		menuList.add(new Menu("GN001D100","GN001D000","权限管理","/admin","Y"));
		menuList.add(new Menu("GN001D110","GN001D100","密码修改","/admin","Y"));
		menuList.add(new Menu("GN001D120","GN001D100","新加用户","/admin","Y"));
		menuList.add(new Menu("GN001D200","GN001D000","系统监控","/admin","Y"));
		menuList.add(new Menu("GN001D210","GN001D200","在线用户","/admin","Y"));

		//让我们创建树
		MenuTree menuTree =new MenuTree(menuList);
		menuList=menuTree.builTree();
		//转为json看看效果
		String jsonOutput= JSON.toJSONString(menuList);
		System.out.println(jsonOutput);
	}
}

总结:要仔细观察,和琢磨,不能走马观花,看获取子节点时,仔细些,思考为什么要这么写,什么是递归,真正的理解递归的思想,就没有啥难度了。

后期追加,JDK 8 版本:
实体类: Tree , 注意这里的构造方法

@Data
public class Tree {
	public Tree() {
		
	}

	public Tree(String id, String pid, String name) {
		this.id = id;
		this.pid = pid;
		this.name = name;
	}

	String id;
	String pid;
	String name;
	List<Tree> child;
}
public static void main(String[] args) {
		List<Tree> treeList = new ArrayList<>();
		//大哥的 PID  在这种写法里面不能为 null,负责 下面 filter 的时候会报错,因为它需要遍历对比
		treeList.add(new Tree("0","","老大"));
		treeList.add(new Tree("2","0","老二"));
		treeList.add(new Tree("3","2","老三"));
		treeList.add(new Tree("5","3","老四"));
		treeList.add(new Tree("6","3","老四"));
		treeList.add(new Tree("4","2","老三"));
		treeList.add(new Tree("7","4","老四"));

		String id = "0";
		//包含本级,不需要可以删除
		Tree tree = treeList.stream().filter(m -> m.getId().equals(id)).collect(Collectors.toList()).get(0);
		List<Tree> test = test(treeList, id);
		tree.setChild(test);
		System.out.println("第一种方法:"+tree);
		List<Tree> trees = test1(treeList, id);
		System.out.println("第二种方法:"+trees);

	}

	public static List<Tree> test1(List<Tree> treeList,String id){
		//获取父节点
		List<Tree> resultList = new ArrayList<>(); //不需要本级可直接删除
		List<Tree> collect = treeList.stream().filter(m -> {
			//添加自己
			if (m.getId().equals(id)) resultList.add(m); 不需要本级可直接删除
			return m.getPid().equals(id);
		}).map(
				(m)->{
					m.setChild(getChild1(m,treeList));
					return m;
				}
		).collect(Collectors.toList());
		//把自己的儿子添加到自己下面,不需要本级可直接删除,返回 collect 
		if (resultList.size()>0) resultList.get(0).setChild(collect);
		return resultList;
	}
	private static List<Tree> getChild1(Tree tree, List<Tree> treeList) {
		//获取字节点
		List<Tree> collect = treeList.stream().filter(m -> m.getPid().equals(tree.getId())).map(
				(m)->{
					m.setChild(getChild(m,treeList));
					return m;
				}
		).collect(Collectors.toList());
		return collect;
	}



	public static List<Tree> test(List<Tree> treeList,String id){
		//获取父节点
		List<Tree> collect = treeList.stream().filter(m -> m.getPid().equals(id)).collect(Collectors.toList());
		collect.stream().forEach(m->m.setChild(getChild(m,treeList)));
		return collect;
	}
	private static List<Tree> getChild(Tree tree, List<Tree> treeList) {
		//获取字节点
		List<Tree> collect = treeList.stream().filter(m -> m.getPid().equals(tree.getId())).collect(Collectors.toList());
		collect.stream().forEach(m->m.setChild(getChild(m,treeList)));
		return collect;
	}

原文链接Java递归生成树状结构菜单

  • 19
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }
可以用Java实现递归计算树结构当前节点包含多少级,代码如下: ```java public int getLevel(TreeNode node) { if (node == null || node.children.isEmpty()) { return 0; } else { int maxChildLevel = 0; for (TreeNode child : node.children) { int childLevel = getLevel(child); if (childLevel > maxChildLevel) { maxChildLevel = childLevel; } } return maxChildLevel + 1; } } ``` 其中,`TreeNode` 表示树节点,`node.children` 表示当前节点的子节点列表。该函数的返回值为当前节点包含的最大级数加 1。 示例用法: ```java // 构造一颗树 TreeNode root = new TreeNode("A"); TreeNode b = new TreeNode("B"); TreeNode c = new TreeNode("C"); TreeNode d = new TreeNode("D"); TreeNode e = new TreeNode("E"); TreeNode f = new TreeNode("F"); TreeNode g = new TreeNode("G"); TreeNode h = new TreeNode("H"); root.addChild(b); root.addChild(c); b.addChild(d); b.addChild(e); c.addChild(f); c.addChild(g); e.addChild(h); // 计算节点级数 int levelA = getLevel(root); int levelB = getLevel(b); int levelC = getLevel(c); int levelD = getLevel(d); int levelE = getLevel(e); int levelF = getLevel(f); int levelG = getLevel(g); int levelH = getLevel(h); // 输出结果 System.out.println("Level of A: " + levelA); // Output: 2 System.out.println("Level of B: " + levelB); // Output: 1 System.out.println("Level of C: " + levelC); // Output: 1 System.out.println("Level of D: " + levelD); // Output: 0 System.out.println("Level of E: " + levelE); // Output: 1 System.out.println("Level of F: " + levelF); // Output: 0 System.out.println("Level of G: " + levelG); // Output: 0 System.out.println("Level of H: " + levelH); // Output: 0 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值