您的位置:首页 > 产品设计 > UI/UE

树型构建器-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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: