树形结构很常见,最典型就是管理系统中的菜单,比如用户管理下,有新增用户,删除用户等等.
数据库表中的存储结构 一般会有一个id 以及一些业务字段 最后一定要有一个父id 存储上一级的id
这样就建立了一个级联关系,我这里就没有去查询数据库了,直接创建几个记录即可.
菜单实体类
public class Menu {
private Integer id;
private String name;
private String url;
private Integer fatherId;
public Menu(Integer id, String name, String url, Integer fatherId) {
this.id = id;
this.name = name;
this.url = url;
this.fatherId = fatherId;
}
@Override
public String toString() {
return "Menu{" +
"id=" + id +
", name='" + name + '\'' +
", url='" + url + '\'' +
", fatherId=" + fatherId +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getFatherId() {
return fatherId;
}
public void setFatherId(Integer fatherId) {
this.fatherId = fatherId;
}
}
在新建一个类,和这个菜单实体类相同,但是多一个子节点属性,存放所有的子节点,其实这个不建,就在菜单实体类多加一个子节点属性也可以
public class MenuVo {
private Integer id;
private String name;
private String url;
private Integer fatherId;
private List childNode;
@Override
public String toString() {
return "MenuVo{" +
"id=" + id +
", name='" + name + '\'' +
", url='" + url + '\'' +
", fatherId=" + fatherId +
", childNode=" + childNode +
'}';
}
public MenuVo() {
}
public MenuVo(Integer id, String name, String url, Integer fatherId, List childNode) {
this.id = id;
this.name = name;
this.url = url;
this.fatherId = fatherId;
this.childNode = childNode;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getFatherId() {
return fatherId;
}
public void setFatherId(Integer fatherId) {
this.fatherId = fatherId;
}
public List getChildNode() {
return childNode;
}
public void setChildNode(List childNode) {
this.childNode = childNode;
}
}
接下来贴出测试代码
public class Test {
public static void main(String[] args) {
List
sqlData.add(new Menu(1,"1","xxx",-1));
sqlData.add(new Menu(2,"1-1","xxx",1));
sqlData.add(new Menu(3,"1-1-1","xxx",2));
sqlData.add(new Menu(4,"2","xxx",-1));
sqlData.add(new Menu(5,"2-1","xxx",4));
sqlData.add(new Menu(6,"1-2","xxx",1));
//存储非根节点
List tempList=new ArrayList<>();
//存储最终的结果
List resultList=new ArrayList<>();
//遍历数据库查询数据集合,如果父id==-1 代表根节点 添加到最终结果中,否则为非根节点添加到临时节点
for (Menu menu : sqlData) {
if(menu.getFatherId()==-1){
resultList.add(new MenuVo(menu.getId(),menu.getName(),menu.getUrl(),menu.getFatherId(),new ArrayList<>()));
}else{
tempList.add(new MenuVo(menu.getId(),menu.getName(),menu.getUrl(),menu.getFatherId(),new ArrayList<>()));
}
}
//遍历所有的根节点,通过根节点和非根节点集合,找到这个根节点的所有子节点
for (MenuVo menuVo : resultList) {
getChildNode(tempList,menuVo);
}
resultList.forEach(System.out::println);
}
public static void getChildNode(List tempList,MenuVo fatherNode ){
for (MenuVo menuVo : tempList) {
//如果该节点的父id为传进来父节点的id 那么就为其子节点
if(menuVo.getFatherId()==fatherNode.getId()){
//添加到子节点数组
fatherNode.getChildNode().add(menuVo);
//递归调用 继续找该子节点 是否还有子节点
getChildNode(tempList,menuVo);
}
}
}
}
大致思路就是,先区分根节点和非根节点,然后遍历根节点,根据根节点的id,去非根节点中找父id
为根节点id的节点,添加到根节点的子节点集合中,但是由于子节点还可能有子节点,就是这个树有
多少层级,我们并不知道,所以在查找子节点时需要递归,将每一个子节点作为一个父节点继续去查找他的子节点
标签:java,name,url,fatherId,id,树形,节点,public,结构
来源: https://www.cnblogs.com/java888/p/12731907.html