关于java:java返回树形结构数据工具类

31次阅读

共计 3327 个字符,预计需要花费 9 分钟才能阅读完成。

创立树公共接口

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

正文完
 0