树型构建器-TreeBuilder
2020-07-19 04:48
495 查看
Tree类,entity需要继承此类
package org.blade.personal.utils.treebuilder;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Transient;
@SuppressWarnings("hiding")
public class Tree {
@Transient
private List<Tree> children = new ArrayList<Tree>();
@Transient
private boolean removed;
private Long parentId;
private Long id;
public List<Tree> getChildren() {
return children;
}
public void setChildren(List<Tree> children) {
this.children = children;
}
public boolean isRemoved() {
return removed;
}
public void setRemoved(boolean removed) {
this.removed = removed;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void addChild(Tree tree){
this.children.add(tree);
}
}
[/code]
TreeBuilder类,与之前的版本相比当前可以支持实体查询反回的结果
package org.blade.personal.utils.treebuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.alibaba.fastjson.JSON;
public class TreeBuilder {
/**
* 算法思想是: 使用map 作id 与记录的映射, 第一步把root节点找出并标记为删除;
* 第二步遍历记录列表取出每个的父id,然后到映射里找到相应的记录parent,把当前记录作为parent的children;
* 第三步把收集器里的记录转换成list。
*
* 注意:这里使用了Map 数据结构 与 java 的 引用特性;虽然map 与 picking 是两次遍历
* records,但里面相同的key的记录引用 是 指向相同的内存的。
**/
public static List builder(List<Tree> records) {
// 映射id与记录成为 {id : record}
Map<Long, Tree> map = new HashMap<Long, Tree>();
for (Tree su : records) {
map.put(su.getId(), su);
}
// 收集
Map<Long, Tree> picking = new HashMap<Long, Tree>();
for (Tree su : records) {
Long parentId = su.getParentId();
boolean removed = su.isRemoved();
if (0 == parentId && !removed) {// 父id为0,此时为root
picking.put(su.getId(), su);
su.setRemoved(true);// 标记为删除,不可真删除,否则会报currencyXXXX的异常
}
}
// 构建树
for (Tree su : records) {
Long parentId = su.getParentId();
boolean removed = su.isRemoved();
if (0 != parentId && !removed) {
Tree parent = map.get(parentId);// 取出映射中的记录
if (parent.getChildren().size() > 0) {// 是否有子节点,有把当前记录作为子节点
List<Tree> children = parent.getChildren();
children.add(su);
} else {// 无,则添加子节点容器,再把当前记录作为子节点
List<Tree> children = new ArrayList<Tree>();
children.add(su);
parent.setChildren(children);
}
// 标记为删除,不可真删除,否则会报currencyXXXX的异常
su.setRemoved(true);
}
}
// 转为list
List<Tree> result = new ArrayList();
Set<Long> keySet = picking.keySet();
for (Long key : keySet) {
Tree resultItem = map.get(key);
result.add(map.get(key));
}
return result;
}
public static void main(String[] args) {
Tree node1 = new Tree();
node1.setId(1L);
node1.setParentId(0L);
Tree node2 = new Tree();
node2.setId(2L);
node2.setParentId(1L);
Tree node3 = new Tree();
node3.setId(3L);
node3.setParentId(1L);
Tree node4 = new Tree();
node4.setId(4L);
node4.setParentId(3L);
Tree node5 = new Tree();
node5.setId(5L);
node5.setParentId(4L);
List list = new ArrayList();
list.add(node1);
list.add(node2);
list.add(node3);
list.add(node4);
list.add(node5);
List treeList = TreeBuilder.builder(list);
System.out.println(JSON.toJSONString(treeList));
/* [{"children":[{"children":[],"id":2,"parentId":1,"removed":true},
{"children":[{"children":[{"children":[],"id":5,"parentId":4,"removed":true}],
"id":4,"parentId":3,"removed":true}],"id":3,"parentId":1,"removed":true}],
"id":1,"parentId":0,"removed":true}]*/
}
}
[/code]
转载于:https://my.oschina.net/zhanggf1988/blog/508313
相关文章推荐
- 树型下拉框组件的构建
- 用TreeView构建树型目录
- 使用dtree构建动态树型菜单
- 用TreeView构建树型目录(C#版)
- 使用dtree构建动态树型菜单
- 使用dtree构建动态树型菜单
- 从数据库中读出树形数据,并快速构建树型类关系
- linq to xml/动态类型 从树型表构建树(linq to entity处理数据库)
- 用TreeView构建树型目录(C#版)
- dtree和jquery构建树型结构
- 使用dtree构建动态树型菜单
- 用 SQL 查询/构建树型(层次)数据
- 利用Javascript读取xml文件,构建树型列表
- dtree和jquery构建树型结构
- 初学 ASP.NET AJAX (一):构建 ASP.NET AJAX 开发环境
- 快速构建一个简单的个人框架系列
- javascript 和HTML5 利用canvas构建 猜牌游戏(让我猜猜你心中的牌)
- 第四十三题 通过前序遍历和中序遍历构建二叉树
- MySQL Study之--MySQL Cluster(集群)构建
- 【项目管理和构建】——Maven简介(一)