创建树公共接口
/**
* 树公共接口
* 需要包装成树形结构的实体继承此类,并添加List children属性
*
* @author jinlong
* @date 2019-06-28
*/
public interface TreeMixin {
/**
* 获取子节点
*
* @return List
*/
List getChildren();
/**
* 设置子节点
*
* @param children 子节点列表
*/
void setChildren(List children);
/**
* 添加子节点
*
* @param child 子节点
*/
default void addChild(T child) {
List children = getChildren();
if (children == null) {
children = new ArrayList<>();
}
children.add(child);
}
}
【java返回树形结构数据工具类】创建返回树结构实体类
@Data
public class DepartDto implements TreeMixin {
/**
* DepartDto的唯一标识
*/
private String key;
private Long id;
private String name;
/**
* 可以是员工工号或部门代码
*/
private String code;
private Long parentId;
/**
* 子部门
*/
private List children = new ArrayList<>();
@Override
public List getChildren() {
return children;
}@Override
public void setChildren(List children) {
this.children = children;
}/**
*
* @param depart
*/
public void fillDepart(Department depart){
this.setKey("d"+depart.getId());
this.setName(depart.getName());
this.setParentId(depart.getParentId());
this.setId(depart.getId());
}
创建树辅助类
/**
* 树辅助类
*
* @param 节点类型
* @param id类型
* @author jinlong
* @date 2019-06-28
*/
public class TreeUtil {
/**
* id获取方法
*/
private Function idGetter;
/**
* 父节点id获取方法
*/
private Function parentIdGetter;
public TreeUtil(Function idGetter, Function parentIdGetter) {
this.idGetter = idGetter;
this.parentIdGetter = parentIdGetter;
}/**
* 转化为树形结构
*
* @return
*/
public T buildTree(List list, T root) {
List children = buildTreeList(list, idGetter.apply(root));
root.setChildren(children);
return root;
}/**
* 构建树
*
* @param list 待转化的数据列表
* @return
*/
public List buildTreeList(List list, R rootId) {
ArrayList dest = new ArrayList<>(Collections.nCopies(list.size(), null));
Collections.copy(dest, list);
Map idItemsMap = dest.stream().collect(Collectors.toMap(item -> idGetter.apply(item), item -> item));
dest.forEach(item -> {
R parentId = parentIdGetter.apply(item);
Optional.ofNullable(idItemsMap.get(parentId)).ifPresent(parent -> parent.addChild(item));
});
return dest.stream().peek(d -> {
if (CollectionUtils.isEmpty(d.getChildren())) {
d.setChildren(null);
}
}).filter(matchParentId(rootId)).collect(Collectors.toList());
}private Predicate matchParentId(R parentId) {
return item -> Objects.equals(parentIdGetter.apply(item), parentId);
}
}
获取树形结构具体方法 这是具体流程 获取什么数据还需根据自己的业务来获取
/**
* 查询组织架构数据(部门加员工)
* @param onlyWorking 是否只查询在职的
* @return
*/
public DepartDto treeHasEmployee(Boolean onlyWorking) {
//获取全部的部门列表
List list = findAll();
//获取根部门
Department rootDept = findRoot();
//获取根部门id
Long rootId = rootDept.getId();
//创建树形结构数据对象
DepartDto root = new DepartDto();
//获取全部员工
List userList = workInfoService.list();
//创建一个和员工集合大小一样的集合 泛型为树形结构的实体类
List dtoList =Lists.newArrayListWithExpectedSize(userList.size());
//将员工集合转换为树形结构的实体类
userList.forEach(u -> {
DepartDto dto = new DepartDto();
dto.setKey(u.getId().toString());
dto.setName(u.getName());
dto.setParentId(u.getDepartmentId());
dto.setId(u.getId());
dto.setCode(u.getJobNumber());
dtoList.add(dto);
});
//将部门集合转换为树形结构的实体类
for (Department d : list) {
//判断是否为根节点
if (d.getId().equals(rootId)) {
//为根节点时 将数据转换为树形结构不做任何操作
root.fillDepart(d);
} else {
//为子节点将数据转换为树形结构并且加入到dtoList中
DepartDto dto = new DepartDto();
dto.fillDepart(d);
dtoList.add(dto);
}
}
//创建树形工具类对象 调用树形工具全参构造方法参数为 参数为:
//@paramgetId方法获取数据id方法
//@param getParentId方法获取父id方法
TreeUtil treeUtil = new TreeUtil<>(DepartDto::getId, DepartDto::getParentId);
//调用树形工具类的buildTree方法 参数是
// @param dtoList 所有子节点集合 泛型为树形结构实体类
// @param root根部门
return treeUtil.buildTree(dtoList, root);
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)