嗯。。。两种构造树型数据的方法
先贴实体类
/**
* 实体类
*
* @ClassName Model
* @Description TODO
* @author wucx
* @time 2018-02-11 09:34
*/
public class Model {
private String id;// 主键
private String pid;// 父主键
private List<Model> children;// 子节点
public Model()
{
children = new ArrayList<Model>();
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getPid()
{
return pid;
}
public void setPid(String pid)
{
this.pid = pid;
}
public List<Model> getChildren()
{
return children;
}
public void setChildren(List<Model> children)
{
this.children = children;
}
}
然后贴第一种方法
/**
* 第一种方法,循环使用<br>
*
* 原理:两层循环<br>
* 第一层循环:先取出第一个节点<br>
* 标记是否为子节点 第二层循环:<br>
* 取出一个节点,进行判断,第一层取出的节点是否为第二个节点的子节点,<br>
* 若是,则添加进第二个节点中,第二层循环结束,第一层循环取下一个节点<br>
* 若不是,则第二层循环取下一个节点,然后继续判断<br>
* 直到成功或第二层循环循环结束 <br>
* 然后判断标记是否触发,若没有,则说明为一层节点,添加<br>
*
* @author wucx
* @Title ListToTree
* @param list---原数据(未转换的数据,可以从数据库中查出)
* @param pId---该节点及该节点下的数据不返回
* @return
*/
private List<Model> ListToTree(List<Model> list, String pId)
{
List<Model> tree = new ArrayList<Model>();
// 如果原数据为空,则直接返回
if (list.size() == 0)
{
return tree;
}
for (Model n1 : list)
{
// 标记是否为父节点
boolean mark = true;
for (Model n2 : list)
{
// 如果n1为n2的子节点,则将n1添加到n2的子节点中去
if (n1.getPid().equals(n2.getId()))
{
// 标记父节点改变
mark = false;
if (!(pId != null && n1.getId().equals(pId)))
{
// 如果未初始化,则初始化,防止空异常
if (n2.getChildren() == null)
{
n2.setChildren(new ArrayList<Model>());
}
n2.getChildren().add(n1);
}
break;
}
}
// 如果标记为true,则代表为第一层节点之一,添加
if (mark)
{
if (!(pId != null && n1.getId().equals(pId)))
{
tree.add(n1);
}
}
}
return tree;
};
第二种方法
/**
* 第二种方法,利用数据库来建树<br>
* 原理:根据父节点来查找其全部子节点<br>
* 然后将其放置在其子节点中<br>
* 并继续递归其子节点<br>
* 直到返回空<br>
* 很浪费数据库的资源,但是时间复杂度很低
* @author wucx
* @Title getTree
* @Description TODO
* @time 2018-02-11 10:14
* @param pid
* @return
*/
private List<Model> getTree(String pid){
//根据父id查找其子节点
List<Model> tree = getModels(pid);
for (Model model : tree)
{
//递归该方法,来查找该其子节点的子节点
model.setChildren(getTree(model.getId()));
}
return tree;
}
//模拟数据库中查询方法
private List<Model> getModels(String pid){
return null;
}
然后顺便再贴一个从树中查子节点的方法
/**
* 在子节点中查找节点
*
* @author wucx
* @Title findModelByModel
* @param parent---已经树形好的父节点
* @param id---需要查找的节点id
* @return
*/
private Model findModelByModel(Model parent, String id)
{
// 返回的节点
Model model = null;
// 自身也需要判断
if (parent.getId().equals(id))
{
return parent;
}
// 获取子节点
List<Model> children = parent.getChildren();
for (Model n : children)
{
// 找到了,直接返回
if (n.getId().equals(id))
{
return n;
}
// 否者查找其的子节点
List<Model> c = n.getChildren();
// 如果子节点不为空,则继续递归子节点中查找该特定节点
if (c != null && !c.isEmpty() && c.size() != 0)
{
model = findModelByModel(n, id);
// 如果不为空,则找到,否则继续循环
if (model != null)
{
return model;
}
}
}
// 如果返回的是这个,则说明没有找到,返回空
return model;
}
原理什么的在注释中都有,就懒得贴出来了,然后这些是根据写的项目中剥离出来的小demo,只是大概体现一些思路和原理,demo是随手写的,不保证能用,还有查询的时候可以根据需要自行添加查询的字段,当然,如果有一些更好的构造树的方法欢迎介绍