java 生成easyui 所需要的森林

  在项目中,可能会遇到机构树这种格式,但是数据库存储的数据 不能维护这样子的树,所以需要中间转换来完成,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节点是无效的,在返回结果集合的时候需要剔除掉

运行结果:

  

原文地址:https://www.cnblogs.com/tickobject/p/4161103.html