树形结构之二 运用递归加载你想要的结构
接着上面的一往篇,继续说树型结构的事。
?
上面一篇提到如何建立一个业务无关的结点,下面就要说一下树的组装。
?
设计思想是调用者通过TreeBuilder的构造方法加载所有结点,根据不同的需求通过TreeBuilder提供的方法得到相应的信息。
待树型结构被装配完成,通过拿到一个根结点就可以拿出整棵树的信息。
?
一点一点来吧:
?
--------------------------------------------
?
public class TreeBuilder<T> {private static Logger logger = Logger.getLogger(TreeBuilder.class);protected boolean inited=false;//是否已经初始化private List<Node<T>> nodes;//根结点以外的结点private Node<T> root;//根结点public TreeBuilder(Node<T> root,List<Node<T>> nodes){if (root == null) {throw new RuntimeException("未指定根结点!");}if (nodes == null || nodes.size() == 0) {throw new RuntimeException("没有叶子结点不能生成树!");;}this.root=root;this.nodes=nodes;}}
?
?从以上代码中可以得到以下信息:
1.它是一个泛型类,类型与结点的扩展属性的类型保持一致。
2.它要求一次性加载所有结点。
?
下面是一重要方法:
1.装配树型结构:
?
?
/** * 装配树 * @param node * @param grade结点级别 * @param setParent 是否设置父结点,有时候没有必要设置,这样可以减少流量 */protected void setupTree(Node<T> node, int grade,boolean setParent) {for (Node<T> n : nodes) {if (n.getParentId().equals(node.getId())) {n.setGrade(grade);node.addChild(n);if (n.getParentId().equals(root.getId())) {n.setIsexpand(true);}setupTree(n, grade + 1,setParent);//递归装配所有结点,这里有个不妥,未进行循环引用检测}if(setParent){n.setParent(node);}}}
?
2.对结点进行排序
?
?
/** * 对结点进行排序 * @param node */public void sort(Node<T> node){if (node==null) {return;}if(node.getChildren()!=null&&node.getChildren().size()>0){for (Node<T> n:node.getChildren()) {sort(n);}Collections.sort(node.getChildren());}}
?
3.实用方法-得到经过排序的根结点
?
?
/** * 得到根结点 * @return */public Node<T> getRoot() {if (!inited) {init(false);}sort(root);return root;}?
4. 设置所有结点包含结点的最大深度
?
?
/** * 设置各个结点下面包含结点的最深层次 * @throws Exception */protected void setupSubLevelsNum() throws Exception {if (!inited) {init(false);}if(nodes==null)return;for (Node<T> n : getLeaves()) {int i=1;while(n.getParent()!=null){Node<T> parent=n.getParent();if(parent.getSubLevels()<i)parent.setSubLevels(i++);n=parent;}}root.setSubLevels(getMaxLevel());}?
5. 得到已经设置好最深层次的树的根结点
?
?
public Node<T> getKnowSubLevelsRoot() throws Exception {setupSubLevelsNum();return root;}?
6.得到树的深度
?
?
/** * 得到树的最大深度 * @return */public int getMaxLevel() {if (nodes==null||nodes.size()==1) {return 1;}int level=1;for(Node<T> node:getLeaves()){if (node.getGrade()>level) {level=node.getGrade();}}return level;}
?
7.提到指定结点的所有子结点
?
public List<Node<T>> getChildrenInNodeId(String id) {for (Node<T> n : nodes) {if (n.getId().equals(id)) {return n.getChildren();}}return null;}
?
8.得到指定级别的所有结点
?
?
public List<Node<T>> getNodesInGraged(int grage) throws Exception {if (!inited) {init(false);}List<Node<T>> list = new ArrayList<Node<T>>();for (Node<T> n : nodes) {if (n.getGrade() == grage) {list.add(n);}}return list;}
?
9.得到所有叶子结点
?
?
public List<Node<T>> getLeaves() {List<Node<T>> list = new ArrayList<Node<T>>();for (Node<T> n : nodes) {if (n.getChildren() == null) {list.add(n);}}return list;}
?
?
到此树的常用功能已经整合好了,只要去实例化一个treebuilder就可以做得到一个树型结构了。
?
在下一篇,我会说一些如何在前台展示树型结构的内容,希望大家来捧场。
谢谢大家!!
欢迎留言!
?
?
--------------------------------------------