在项目中,可能会遇到机构树这种格式,但是数据库存储的数据 不能维护这样子的树,所以需要中间转换来完成,zTree可以支持pid,id,name的格式,但是easyui貌似不行,这里就给出刚刚码好的代码:
package com.xxx.pojo; import java.util.ArrayList; import java.util.List; public class ComboTree { private String id; private String text; private String state; private String pid; private String clickFlag; private List<ComboTree> children; public ComboTree() { super(); this.setState("closed"); this.setId("00"); this.setText(null); this.setClickFlag("off"); this.setChildren(new ArrayList<ComboTree>()); } public void clear() { this.setState("closed"); this.setId(null); this.setText(null); this.setChildren(null); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"id":""); sb.append(this.id); sb.append("","text":""); sb.append(this.text); sb.append("","clickFlag":""); sb.append("off"); sb.append("""); if (!this.children.isEmpty()) { sb.append(","state":""); sb.append(this.state); sb.append("","children":["); boolean flag = false; for (ComboTree c : this.children) { if (flag) sb.append(","); else flag = true; sb.append(c.toString()); } sb.append("]"); } sb.append("}"); return sb.toString(); } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public void addChildren(ComboTree ct) { this.children.add(ct); // System.out.println("add"); } //添加一个节点 public boolean addNode(ComboTree ct){ //如果需要添加的节点的PID 为当前节点的ID, 则直接 //添加, 返回true if(this.id == ct.pid || (this.id != null && ct.pid != null && this.id.equals(ct.pid))){ this.children.add(ct); return true; } //委托给子节点 for(ComboTree cct: this.children){ if(cct.addNode(ct)) return true; } //无法添加成功 return false; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getState() { return state; } public void setState(String state) { this.state = state; } public List<ComboTree> getChildren() { return children; } public void setChildren(List<ComboTree> children) { this.children = children; } public String getClickFlag() { return clickFlag; } public void setClickFlag(String clickFlag) { this.clickFlag = clickFlag; } }
package com.xxx.util; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; import com.abc.pojo.ComboTree; public class TreeHelper { /** * 输入无序的ComboTree 获得 List 类型的森林 * @param list0 无序ComboTree节点 * @return List<ComboTree> 森林 * */ @SuppressWarnings("null") public static List<ComboTree> makeTree(List<ComboTree> list0) throws Exception{ //以pId为Key,而以pid为相同的ComboTree作为List为Value Map<String,List<ComboTree>> mapForPid = new HashMap<String,List<ComboTree>>(); //以Id为Tree, 用来快速寻找到RootPID Map<String,ComboTree> mapForId = new HashMap<String,ComboTree>(); //root pid set Set<String> rps = new HashSet<String>(); //构造 两种类型的map for(ComboTree ct : list0){ //构造ID Map mapForId.put(ct.getId(), ct); //PID Map 构造 String pid = ct.getPid(); List<ComboTree> lct = mapForPid.get(pid); if(lct == null){ //构造 Value类型 lct = new LinkedList<ComboTree>(); mapForPid.put(pid, lct); } //添加这个节点 lct.add(ct); } //制作rootPidSet { //已经被寻找过的ID Set<String> keySet = new HashSet<String>(); //寻找RootPID for(String key : mapForId.keySet()){ //沿pid 直到rootPID while(true){ //已经处理过这种节点, //那么可以肯定该节点所在的rootPid已经被添加 if(keySet.contains(key)){ break; } //添加到keySet中, 表示该节点已经被处理 keySet.add(key); ComboTree ct = mapForId.get(key); if(ct == null){ //如果ct为null, 则表示该Key就是一个rootPID rps.add(key); break; } //下一个Pid key = ct.getPid(); } } } //虚拟root结果树 List<ComboTree> vts = new LinkedList<ComboTree>(); //对所有的root Pid 进行处理 for(String key : rps){ List<String> queue = new LinkedList<String>(); ComboTree vt = new ComboTree(); vt.setId(key); vt.setPid(null); vt.setText("虚拟节点"); //添加根Id queue.add(key); while(!queue.isEmpty()){ String pid = queue.remove(0); List<ComboTree> list = mapForPid.get(pid); //没有pid对应的子树 if(list == null) continue; for(ComboTree ct : list){ //添加到queue中 queue.add(ct.getId()); //插入到正确的位置 if(!vt.addNode(ct)){ throw new Exception(ct+"无法插入到Tree中"); } } } vts.add(vt); } //整理res结果 List<ComboTree> res = new LinkedList<ComboTree>(); for(ComboTree vct : vts){ //虚拟PID节点不能作为真实根节点 for(ComboTree ct: vct.getChildren()){ //添加真实节点 res.add(ct); } } return res; } public static ComboTree getComboTree(String id,String pid,String name){ ComboTree t = new ComboTree(); t.setId(id); t.setPid(pid); t.setText(name); return t; } public static void main(String[] args) throws Exception { List<ComboTree> list = new LinkedList<ComboTree>(); list.add(getComboTree("0",null,"root")); list.add(getComboTree("1","0","root")); list.add(getComboTree("2","0","root")); list.add(getComboTree("3","2","root")); list.add(getComboTree("4","3","root")); list.add(getComboTree("5","4","root")); list.add(getComboTree("6","2","root")); list.add(getComboTree("A",null,"root")); list.add(getComboTree("B","A","root")); list.add(getComboTree("C","A","root")); list.add(getComboTree("D","B","root")); list.add(getComboTree("a","aaaaa","root")); list.add(getComboTree("aa","a","root")); System.out.println(makeTree(list)); } }
主要函数为makeTree, 需要ComboTree结构支持.
算法的思想为:
搜索rootPID的集合,然后根据rootPID,构建出虚拟树,注意虚拟树,的root节点是无效的,在返回结果集合的时候需要剔除掉
运行结果: