创建树公共接口
/**
* 树公共接口
* 需要包装成树形结构的实体继承此类,并添加List<T> children属性
*
* @author jinlong
* @date 2019-06-28
*/
public interface TreeMixin<T> {
/**
* 获取子节点
*
* @return List
*/
List<T> getChildren();
/**
* 设置子节点
*
* @param children 子节点列表
*/
void setChildren(List<T> children);
/**
* 添加子节点
*
* @param child 子节点
*/
default void addChild(T child) {
List<T> children = getChildren();
if (children == null) {
children = new ArrayList<>();
}
children.add(child);
}
}
创建返回树结构实体类
@Data
public class DepartDto implements TreeMixin<DepartDto> {
/**
* DepartDto的唯一标识
*/
private String key;
private Long id;
private String name;
/**
* 可以是员工工号或部门代码
*/
private String code;
private Long parentId;
/**
* 子部门
*/
private List<DepartDto> children = new ArrayList<>();
@Override
public List<DepartDto> getChildren() {
return children;
}
@Override
public void setChildren(List<DepartDto> 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 <T> 节点类型
* @param <R> id类型
* @author jinlong
* @date 2019-06-28
*/
public class TreeUtil<T extends TreeMixin, R> {
/**
* id获取方法
*/
private Function<T, R> idGetter;
/**
* 父节点id获取方法
*/
private Function<T, R> parentIdGetter;
public TreeUtil(Function<T, R> idGetter, Function<T, R> parentIdGetter) {
this.idGetter = idGetter;
this.parentIdGetter = parentIdGetter;
}
/**
* 转化为树形结构
*
* @return
*/
public T buildTree(List<T> list, T root) {
List<T> children = buildTreeList(list, idGetter.apply(root));
root.setChildren(children);
return root;
}
/**
* 构建树
*
* @param list 待转化的数据列表
* @return
*/
public List<T> buildTreeList(List<T> list, R rootId) {
ArrayList<T> dest = new ArrayList<>(Collections.nCopies(list.size(), null));
Collections.copy(dest, list);
Map<R, T> 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<T> matchParentId(R parentId) {
return item -> Objects.equals(parentIdGetter.apply(item), parentId);
}
}
获取树形结构具体方法 这是具体流程 获取什么数据还需根据自己的业务来获取
/**
* 查询组织架构数据(部门加员工)
* @param onlyWorking 是否只查询在职的
* @return
*/
public DepartDto treeHasEmployee(Boolean onlyWorking) {
//获取全部的部门列表
List<Department> list = findAll();
//获取根部门
Department rootDept = findRoot();
//获取根部门id
Long rootId = rootDept.getId();
//创建树形结构数据对象
DepartDto root = new DepartDto();
//获取全部员工
List<WorkInfo> userList = workInfoService.list();
//创建一个和员工集合大小一样的集合 泛型为树形结构的实体类
List<DepartDto> 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);
}
}
//创建树形工具类对象 调用树形工具全参构造方法参数为 参数为:
//@param getId方法 获取数据id方法
//@param getParentId方法 获取父id方法
TreeUtil<DepartDto, Long> treeUtil = new TreeUtil<>(DepartDto::getId, DepartDto::getParentId);
//调用树形工具类的buildTree方法 参数是
// @param dtoList 所有子节点集合 泛型为树形结构实体类
// @param root 根部门
return treeUtil.buildTree(dtoList, root);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。