创立树公共接口
/** * 树公共接口 * 须要包装成树形构造的实体继承此类,并增加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); }}
创立返回树结构实体类
@Datapublic 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);