因公司业务需求,需要构造各种类型组织关系树。
有同种模型的关系树,例如 单位、子单位关系树
也有不同模型的关系树,例如 单位、子单位、部门、子部门关系树
那么基于这种复杂的关系树,我们需要将树的基本结构关系以及业务代码做分离
源码地址
https://github.com/zhaojun123/tree.git
首先构造一个树的基类
/**
* 树的抽象
*/
public abstract class Tree{
private List<Tree> childrenList = new ArrayList<>();
/**
* 获取树节点id
* @return
*/
abstract Object getTreeId();
/**
* 获取树父节点id
* @return
*/
abstract Object getTreeParentId();
/**
* 该节点的子节点集合
* @return
*/
public List<Tree> getTreeChildrenList(){
return childrenList;
}
/**
* 判断是否是根节点,默认TreeParentId为null即为根节点,子类可以覆盖该逻辑
* @return
*/
protected boolean topParentId(){
return getTreeParentId() == null;
}
}
再模拟实际业务场景构建单位模型 和 部门模型,继承该基类
/**
* 单位模型
*/
public class OrganTree extends Tree{
public OrganTree(String organId,String parentOrganId,String organName){
this.organId = organId;
this.parentOrganId = parentOrganId;
this.organName = organName;
}
/**
* 这里需要将业务字段 和 树的关系字段绑定,确定id 和 parentId
* @return
*/
@Override
public Object getTreeId() {
return organId;
}
@Override
public Object getTreeParentId() {
return parentOrganId;
}
//省略了相应的get set 方法
}
//部门模型
public class DeptTree extends Tree{
public DeptTree(String deptId,String parentDeptId,String organId,String deptName){
this.deptId = deptId;
this.parentDeptId = parentDeptId;
this.organId = organId;
this.deptName = deptName;
}
private String deptId;
private String parentDeptId;
private String organId;
private String deptName;
/**
* 这里需要将业务字段 和 树的关系字段绑定,确定id 和 parentId
* @return
*/
@Override
public Object getTreeId() {
return deptId;
}
@Override
public Object getTreeParentId() {
return parentDeptId;
}
//省略了相应的get set 方法
}
工具类TreeUtils,根据getTreeId、getTreeParentId构建Tree模型的关系
/**
* 构建树的工具类
*/
public class TreeUtils {
public static <T>List<T> tree(List<T> treeList){
return tree(treeList,null);
}
/**
* 在组装树的过程中,调用Consumer函数执行自定义的业务逻辑
* @param treeList
* @param afterAddChildren
* @param <T>
* @return
*/
public static <T> List<T> tree(List<T> treeList, Consumer<Tree> afterAddChildren){
List<T> resultList = new ArrayList();
for(Object object: treeList){
Tree tree = (Tree)object;
if(tree.topParentId()){
resultList.add((T)tree);
treeRecursion(tree,(List<Tree>)treeList,afterAddChildren);
}
}
return resultList;
}
/**
* 递归方法组装树
* @param nodeTree
* @param treeList
* @param afterAddChildren
*/
private static void treeRecursion(Tree nodeTree,List<Tree> treeList,Consumer<Tree> afterAddChildren){
for(Tree tree:treeList){
if(nodeTree.getTreeId().equals(tree.getTreeParentId())){
nodeTree.getTreeChildrenList().add(tree);
treeRecursion(tree,treeList,afterAddChildren);
}
}
if(afterAddChildren!=null)
afterAddChildren.accept(nodeTree);
}
}
测试类
构建几个上下级单位,以及内部的上下级部门,并将其关系用树表现出来
public class TreeTest {
public static void main(String[] args) {
TreeTest treeTest = new TreeTest();
List<OrganTree> organList = treeTest.getOrganList();
List<OrganTree> resultList = TreeUtils.tree(organList
,(tree -> {
//如果树节点是单位,则继续查下面的部门
if(tree instanceof OrganTree){
OrganTree organTree = (OrganTree)tree;
List<DeptTree> deptTreeList
= treeTest.getDeptByOrgan(organTree.getOrganId());
//把部门加入单位的子节点中,继续构造部门树
tree.getTreeChildrenList().addAll(TreeUtils.tree(deptTreeList));
}
}
)
);
System.out.println(new Gson().toJson(resultList));
}
/**
* 模拟数据库查询获取所有公司的列表
* @return
*/
public List<OrganTree> getOrganList(){
List<OrganTree> list = new ArrayList<>();
list.add(new OrganTree("1",null,"中科美络"));
list.add(new OrganTree("2",null,"移动互联"));
list.add(new OrganTree("3","1","中科子公司1"));
list.add(new OrganTree("4","1","中科子公司2"));
return list;
}
/**
* 模拟数据库查询 中科美络 和 子公司2下面的部门
* @param organId
* @return
*/
public List<DeptTree> getDeptByOrgan(String organId){
List<DeptTree> list = new ArrayList<>();
if(organId.equals("4")){
list.add(new DeptTree("1",null,"1","总经办"));
list.add(new DeptTree("2","1","1","人事"));
list.add(new DeptTree("3","1","1","财务"));
list.add(new DeptTree("4","2","1","开发"));
}
if(organId.equals("1")){
list.add(new DeptTree("1",null,"1","总经办"));
}
return list;
}
}
打印
[{
"organId": "1",
"organName": "中科美络",
"childrenList": [{
"organId": "3",
"parentOrganId": "1",
"organName": "中科子公司1",
"childrenList": []
}, {
"organId": "4",
"parentOrganId": "1",
"organName": "中科子公司2",
"childrenList": [{
"deptId": "1",
"organId": "1",
"deptName": "总经办",
"childrenList": [{
"deptId": "2",
"parentDeptId": "1",
"organId": "1",
"deptName": "人事",
"childrenList": [{
"deptId": "4",
"parentDeptId": "2",
"organId": "1",
"deptName": "开发",
"childrenList": []
}]
}, {
"deptId": "3",
"parentDeptId": "1",
"organId": "1",
"deptName": "财务",
"childrenList": []
}]
}]
}, {
"deptId": "1",
"organId": "1",
"deptName": "总经办",
"childrenList": []
}]
}, {
"organId": "2",
"organName": "移动互联",
"childrenList": []
}]
来源:CSDN
作者:yzqingqing
链接:https://blog.csdn.net/yzqingqing/article/details/104684380