这几天在写一个外快,而写之前的TT随笔比较耗时,故先搁着。
前天写了一个树生成器,感觉还是挺不错的,相对来说还是比较灵活的,代码也比较简单。
先贴上生成器的代码:
package com.tt.pub.utils; import java.util.List; import java.util.Stack; /** * Desc:树生成工具。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * */ public class TreeGen { /** * Desc:树生成模板。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * * @param <E> * @param <V> */ public static interface ITreeTmp<E, V> { /** * Desc:将源对象转换为目标对象(树节点)。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * * @param src * @return */ public V trans(E src); /** * Desc:是否将当前node入栈?如果入栈,请记得为节点构造父子关系。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * * @param node * @param lastNode * @return */ public boolean isPush(V node, V lastNode); } /** * Desc:通过有一定规律的数组(请先进行排序),构建树数组。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * * @param srcList * @param tmp * @return */ public static <E, V> List<V> gen(List<E> srcList, ITreeTmp<E, V> tmp){ List<V> treeList = CollUtils.newArrayList(); Stack<V> stack = CollUtils.newStack(); for(int i = 0; i < srcList.size(); ++i){ E src = srcList.get(i); V node = tmp.trans(src); if(stack.size() == 0){//如果栈为空,则为树根 treeList.add(node);//添加为根节点 stack.push(node);//当前元素进栈 continue; } while(stack.size() > 0){//进行栈操作 V lastNode = stack.lastElement();//取顶级元素进行比较 if(tmp.isPush(node, lastNode)) { stack.push(node);//当前元素进栈 break; } else stack.pop();//未匹配到则出栈 } } return treeList; } }
所需要的数据格式如下:
var menuInfos = [{ id : "menu001" },{ id : "menu001001" },{ id : "menu001002" },{ id : "menu001002001" },{ id : "menu002" },{ id : "menu002001" }];
数据按一定顺序排列,并且有一定规则。
使用的范例如下:
先创建一个模板,模板需要实现TreeGen中的ITreeTmp接口:
package com.tt.pvl.tmp; import com.tt.pub.utils.TreeGen.ITreeTmp; import com.tt.pvl.pojo.Pvl; import com.tt.pvl.pojo.TreeNode4EUi; /** * Desc:菜单树模板。 * @author Small * @Email 536762164@qq.com * @since 2013-6-14 * */ public class MenuTreeTmp implements ITreeTmp<Pvl, TreeNode4EUi> { @Override public TreeNode4EUi trans(Pvl src) { TreeNode4EUi node = new TreeNode4EUi(); node.setId(src.getCode()); node.setText(src.getName()); node.setUrl(src.getContent()); return node; } @Override public boolean isPush(TreeNode4EUi node, TreeNode4EUi lastNode) { if(!node.getId().startsWith(lastNode.getId())) return false; lastNode.addChild(node);//构建树层级关系 return true; } }
调用方式:
List<Pvl> menus = pvlService.getByType(PvlConst.PVL_TYPE_MENU); List<TreeNode4EUi> treeList = TreeGen.gen(menus, new MenuTreeTmp());
大概的思路是运用了栈来进行操作:
如果栈为空,那么当前元素就作为根节点;
如果当前元素是栈最后一个节点的子节点,则创建父子关系,并将当前节点推入栈;
如果当前元素不是是栈最后一个节点的子节点,则将元素出栈,继续循环,知道创建父子关系或者栈为空。
后记:
实在惭愧,没有测试完整,指测试了树列表个数为1的,后面测试的时候才发现了bug。其实只要把TreeGen的gen方法中的循环部分的代码对调下就行了~~代码如下:
public static <E, V> List<V> gen(List<E> srcList, ITreeTmp<E, V> tmp){ List<V> treeList = CollUtils.newArrayList(); Stack<V> stack = CollUtils.newStack(); for(int i = 0; i < srcList.size(); ++i){ E src = srcList.get(i); V node = tmp.trans(src); while(stack.size() > 0){//进行栈操作 V lastNode = stack.lastElement();//取顶级元素进行比较 if(tmp.isPush(node, lastNode)) { stack.push(node);//当前元素进栈 break; } else stack.pop();//未匹配到则出栈 } if(stack.size() == 0){//如果栈为空,则为树根 treeList.add(node);//添加为根节点 stack.push(node);//当前元素进栈 continue; } } return treeList; }
相关推荐
SketchUP插件 Tree Maker (树木生成器) SU 草图大师 不会安装插件的可自行查找下教程很简单的
这个程序是一个文件夹目录树生成器,它可以帮助你生成文件夹的目录树并保存到TXT文本文件中。主要功能如下: 选择文件夹:你可以通过点击菜单栏中的“文件”菜单,然后选择文件夹来指定要生成目录树的文件夹路径。...
可将指定目录的所有文件名导出到文本文件中
百度网盘如何生成目录树结构?软件是windows版exe格式的。采用python编写打包好,直接使用。内附使用教程
DelphiAST, Delphi抽象语法树生成器 Delphi的抽象语法树生成器使用 DelphiAST,你可以使用真正的Delphi代码并获得抽象语法树。 一个单位,但没有符号表。FreePascal和and兼容。示例输入unit Unit1;interfac
该程序是在Visual Studio 2003.Net下开发完成。程序包含三种不同的递归分形树算法实现代码,界面简洁清爽,效果直观逼真,代码规范标准。文件不含任何非法**,请放心下载!
攻击树 Chrome的视觉攻击树生成器 初始概念验证版本。 尚未根据用户输入生成树。
改进的树苗生成器Blenders树苗树生成器附加组件的新版本,具有改进,新功能和错误修复对于Blender 2.7: add_curve_sapling_3 对于Blender 2.8: add_curve_sapling_3_2_8 最新: sapling_4新的替代版本“ sapling_4...
树形目录菜单生成器,(JavaScript版本)
RandTree是一个基于MatLab的树模拟器程序,... 为了模拟视觉逼真的树结构,我们使用了概率的分支生成。 该程序旨在生成具有分支分支模式(渐进式分支)的分支结构。 通过更改概率和分支角度,可以生成不同形状的树。
:package:项目树生成器project-tree-generator:package:项目树生成器播放以单击:bullseye:屏幕快照功能1>输入项目树和复制树功能2>通过github存储库生成树( )和分支(主)复制树博客velog-후기
RSyntaxTree:Ruby中的另一个语法树生成器RSyntaxTree是受启发,以Ruby编程语言编写的图形语法树生成器。网页界面可使用的工作网络界面,为 。安装# gem install rsyntaxtree 用法对于Web界面,请参阅用法”部分。 ...
Delphi的抽象语法树生成器使用DelphiAST,您可以获取真实的Delphi代码并获得抽象的语法树。 一次只有一个单位,但没有符号表。 FreePascal和Lazarus兼容。样本输入unit Unit1;interfaceuses Unit2;function Sum (A, ...
使用递归的分形几何树创建者使用分形几何和递归的树生成器@param m 待增长@param 长的分支长度@param mDegradient 衰减因子 m @param lDegradient 衰减因子 l var tree = new Tree (m, long, mDegradient, ...
unity-skill-tree-editor, 示例Unity自定义图形编辑器编辑技能树 统一技能树 ProAlpha版本 0.1用于编辑技能树的Unity自定义图形编辑器。在 https://dl.dropboxusercontent.com/u/26071528/skill tree example/index
该项目被设计为Arbaro树生成器的分支。 但后来从1.0.7版本开始完全重写。 主要目标是创建树生成器,该树生成器可以创建用于计算机游戏(低多边形)的树模式。
树生成器 :scroll: 关于树生成器(结构)。 :rocket: 使用的技术HTML CSS JavaScript :laptop: 如何下载项目 // Clonar o repositório $ git clone ...
rustsai:脾气暴躁(Rust)的盆景树生成器(●'◡'●)
项目树生成器 :package: 项目树生成器