java之TreeUtils生成一切对象树形结构案例
项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现。
TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口。
/** *树节点父类,所有需要使用{@linkplainTreeUtils}工具类形成树形结构等操作的节点都需要实现该接口 * *@param节点id类型 */ publicinterfaceTreeNode { /** *获取节点id * *@return树节点id */ Tid(); /** *获取该节点的父节点id * *@return父节点id */ TparentId(); /** *是否是根节点 * *@returntrue:根节点 */ booleanroot(); /** *设置节点的子节点列表 * *@paramchildren子节点 */ voidsetChildren(List>children); /** *获取所有子节点 * *@return子节点列表 */ List>getChildren(); }
TreeUtils用来生成树形结构,以及获取所有叶子节点等操作
/** *树形结构工具类 * *@authormeilin.huang *@version1.0 *@date2019-08-241:57下午 */ publicclassTreeUtils{ /** *根据所有树节点列表,生成含有所有树形结构的列表 * *@paramnodes树形节点列表 *@param节点类型 *@return树形结构列表 */ publicstatic >List generateTrees(List nodes){ List roots=newArrayList<>(); for(Iterator ite=nodes.iterator();ite.hasNext();){ Tnode=ite.next(); if(node.root()){ roots.add(node); //从所有节点列表中删除该节点,以免后续重复遍历该节点 ite.remove(); } } roots.forEach(r->{ setChildren(r,nodes); }); returnroots; } /** *从所有节点列表中查找并设置parent的所有子节点 * *@paramparent父节点 *@paramnodes所有树节点列表 */ @SuppressWarnings("all") publicstatic voidsetChildren(Tparent,List nodes){ List children=newArrayList<>(); ObjectparentId=parent.id(); for(Iterator ite=nodes.iterator();ite.hasNext();){ Tnode=ite.next(); if(Objects.equals(node.parentId(),parentId)){ children.add(node); //从所有节点列表中删除该节点,以免后续重复遍历该节点 ite.remove(); } } //如果孩子为空,则直接返回,否则继续递归设置孩子的孩子 if(children.isEmpty()){ return; } parent.setChildren(children); children.forEach(m->{ //递归设置子节点 setChildren(m,nodes); }); } /** *获取指定树节点下的所有叶子节点 * *@paramparent父节点 *@param 实际节点类型 *@return叶子节点 */ publicstatic >List getLeafs(Tparent){ List leafs=newArrayList<>(); fillLeaf(parent,leafs); returnleafs; } /** *将parent的所有叶子节点填充至leafs列表中 * *@paramparent父节点 *@paramleafs叶子节点列表 *@param 实际节点类型 */ @SuppressWarnings("all") publicstatic voidfillLeaf(Tparent,List leafs){ List children=parent.getChildren(); //如果节点没有子节点则说明为叶子节点 if(CollectionUtils.isEmpty(children)){ leafs.add(parent); return; } //递归调用子节点,查找叶子节点 for(Tchild:children){ fillLeaf(child,leafs); } } }
具体使用方式之声明树节点对象
@Getter @Setter publicclassResourceListVOimplementsTreeNode{ privateLongid; privateLongpid; privateIntegertype; privateStringname; privateStringicon; privateStringcode; privateIntegerstatus; privateList children; @Override publicLongid(){ returnthis.id; } @Override publicLongparentId(){ returnthis.pid; } @Override publicbooleanroot(){ returnObjects.equals(this.pid,0L); } @Override publicvoidsetChildren(Listchildren){ this.children=children; } }
具体使用方式之调用
/** *获取账号的资源树 */ publicListlistByAccountId(LongaccountId){ returnTreeUtils.generateTrees(BeanUtils.copyProperties(mapper.selectByAccountId(userId),ResourceListVO.class)); }
通过使用TreeUtils工具可以统一方便地生成一切对象的树形结构以及其他一些对树的操作,避免对每个对象都用特定代码生成。使用起来就是几个字简洁方便爽歪歪biu特否。
补充知识:TreeUtil数据库菜单生成无限级树形结构
1、项目需求:
从数据库从加载所有的菜单出来,菜单中有
id,parentId,name字段
希望能有一个工具帮我进行树形结构重组;
实例类:
packagecom.lming.chcservice.util; importlombok.Data; importjava.util.List; @Data publicclassTreeNode{ /** *节点id */ privateStringid; /** *父节点默认0为根节点 */ privateStringparentId; /** *节点名称 */ privateStringname; /** *是否有子节点 */ privatebooleanhasChild; publicTreeNode(Stringid,StringparentId,Stringname){ this.id=id; this.parentId=parentId; this.name=name; } }
工具类:
packagecom.lming.chcservice.util; importjava.util.ArrayList; importjava.util.LinkedHashMap; importjava.util.List; importjava.util.Map; /** *树形结构工具类 * *将一组list对象转成树形结构 *该list需符合设定的字段类型 * */ publicclassTreeUtil{ publicstaticMapmapArray=newLinkedHashMap (); publicList menuCommon; publicList
测试结果:
[ { "id":"1", "name":"首页", "parentId":"0", "hasChild":true, "childrens":[ { "id":"3", "name":"预约", "parentId":"1", "hasChildren":false, "childrens":[] } ] }, { "id":"2", "name":"订单", "parentId":"0", "hasChild":true, "childrens":[ { "id":"4", "name":"捐献", "parentId":"2", "hasChild":true, "childrens":[ { "id":"5", "name":"我的订单", "parentId":"4", "hasChild":true, "childrens":[ { "id":"6", "name":"个人中心", "parentId":"5", "hasChild":true, "childrens":[ { "id":"7", "name":"个人中心2", "parentId":"6", "hasChildren":false, "childrens":[] } ] } ] } ] } ] } ]
实力类不一致怎么办?自己写一个实体转换类,将类的对象属性转换成上面的实体类,然后在调用,当然最快的方式直接修改实体类即可用。
以上这篇java之TreeUtils生成一切对象树形结构案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。