欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java使用递归实现Tree数据组装

程序员文章站 2022-05-08 19:12:50
...

基于hutool工具中的方法封装,特此记录一下。

/**
 * 行数据转tree结构数据工具类,核心采用hutool提供的api,进行了简单封装
 * @author lpt
 * @date 2020/11/24
 */
public class BuildTreeUtil {

    /* 默认根级 */
    static final String defaultLevel = StrUtil.isNotEmpty(CommonConstant.TREE_DEFAULT_LEVEL) ? CommonConstant.TREE_DEFAULT_LEVEL : "0";

    /**
     * desc 构建树型数据主方法,采用默认配置项,默认从根级取
     * @param nodeList
     * @return
     */
    public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList){
        return buildTree(nodeList, null, defaultLevel, getDefaultConfig());
    }

    /**
     * 构建树型数据主方法,有扩展字段,采用默认配置项,默认从根级取
     * @param nodeList
     * @param extKeyArr
     * @return
     */
    public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr){
        return buildTree(nodeList, extKeyArr, defaultLevel, getDefaultConfig());
    }
    /**
     * desc 构建树型数据主方法,采用默认配置项,指定层级
     * @param nodeList
     * @param parentId
     * @return
     */
    public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr, String parentId){
        return buildTree(nodeList, extKeyArr, parentId, getDefaultConfig());
    }
    /**
     * desc 构建树型数据主方法,采用自定义返回key配置项
     * @param nodeList
     * @param parentId
     * @param treeNodeConfig
     * @return
     */
    public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr, String parentId, TreeNodeConfig treeNodeConfig){
        if(extKeyArr != null && extKeyArr.length > 0){
            //如果有扩展字段在此处处理
            nodeList.forEach((node)->{
                Map<String, Object> map = BeanUtil.beanToMap(node);
                node.setExtra(BuildTreeUtil.setExtra(map, extKeyArr));
            });
        }
        if(CollUtil.isNotEmpty(nodeList) && StrUtil.isNotEmpty(parentId)){
            if(null == treeNodeConfig){
                return TreeUtil.build(nodeList, parentId);
            }else {
                //转换器
                return TreeUtil.build(nodeList, parentId, treeNodeConfig,
                    (treeNode, tree) -> {
                        tree.setId(treeNode.getId());
                        tree.setParentId(treeNode.getParentId());
                        tree.setWeight(treeNode.getWeight());
                        tree.setName(treeNode.getName());
                        // 扩展属性填充
                        if(CollUtil.isNotEmpty(treeNode.getExtra())){
                            treeNode.getExtra().forEach((key, value)->{
                                tree.putExtra(key, value);
                            });
                        }
                    });
            }
        }
        return CollUtil.newArrayList();
    }

    /**
     * desc 获取默认配置
     * @return TreeNodeConfig
     */
    public static TreeNodeConfig getDefaultConfig(){
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey(StrUtil.isNotEmpty(CommonConstant.ID_KEY) ? CommonConstant.ID_KEY : "key");
        treeNodeConfig.setNameKey(StrUtil.isNotEmpty(CommonConstant.NAME_KEY) ? CommonConstant.NAME_KEY : "title");
        treeNodeConfig.setParentIdKey(StrUtil.isNotEmpty(CommonConstant.PARENT_ID_KEY) ? CommonConstant.PARENT_ID_KEY : "parentId");
        treeNodeConfig.setChildrenKey(StrUtil.isNotEmpty(CommonConstant.CHILDREN_KEY) ? CommonConstant.CHILDREN_KEY : "children");
        treeNodeConfig.setWeightKey(StrUtil.isNotEmpty(CommonConstant.ORDER_KEY) ? CommonConstant.ORDER_KEY : "order");
        return treeNodeConfig;
    }


    /**
     * 设置扩展字段的值
     * @param map
     * @param extKeyList
     * @return
     */
    private static Map setExtra(Map<String, Object> map, String[] extKeyList){
        Map<String, Object> resultMap = CollUtil.newHashMap();
        List<String> list = CollUtil.toList(extKeyList);
        if(CollUtil.isNotEmpty(map) && CollUtil.isNotEmpty(list)){
            list.forEach((key) -> {
                resultMap.put(key, map.get(key));
            });
        }
        return resultMap;
    }

    public static void main(String[] args) {
        // 构建node列表
        // 实用时从数据库查询返回实体类用TreeNode(hutool中封装树结构的类,sql中as的key需要和该类中的属性名对应上)
        // 例:select t.id id, t.parent_id parentId, t.title name,t.order weight t from u_menu_t t
        List<TreeNode<Object>> nodeList = CollUtil.newArrayList();
        nodeList.add(new FunctionList("1", "0", "系统管理", 5, "menu1", "/url/page1", "desc", 1,3));
        nodeList.add(new FunctionList("11", "1", "用户1管理", 2, "menu2", "/url/page1", "desc", 1,3));
        nodeList.add(new FunctionList("12", "1", "用户2管理", 1, "menu3", "/url/page1", "desc", 1,3));
        nodeList.add(new FunctionList("111", "11", "用户添加", 0, "menu4", "/url/page1", "desc", 1,3));
        nodeList.add(new FunctionList("2", "0", "店铺管理", 1, "menu5", "/url/page1", "desc", 1,3));
        nodeList.add(new FunctionList("21", "2", "商品管理", 44, "menu6", "/url/page1", "desc", 1,3));
        /*模拟查询数据库结束*/
        /* 扩展字段 */
        System.out.println("基础字段有id、parentId、name、weight(即为hutool中TreeNode类的基础字段)");
        System.out.println("带扩展字段演示");
        String[] extKeyArr = {"icon", "path", "desc", "level", "type"};
        List<Tree<Object>> treeList = BuildTreeUtil.buildTree(nodeList, extKeyArr);
        System.out.println(treeList);
        System.out.println("-----------------------------------------------------------");

        System.out.println("不带扩展字段演示");
        List<TreeNode<Object>> nodeList1 = CollUtil.newArrayList();
        nodeList1.add(new FunctionList("1", "0", "系统管理", 5, null, null, null, null,null));
        nodeList1.add(new FunctionList("11", "1", "用户1管理", 2, null, null, null, null,null));
        nodeList1.add(new FunctionList("12", "1", "用户2管理", 1, null, null, null, null,null));
        nodeList1.add(new FunctionList("111", "11", "用户添加", 0, null, null, null, null, null));
        nodeList1.add(new FunctionList("2", "0", "店铺管理", 1 , null, null, null, null, null));
        nodeList1.add(new FunctionList("21", "2", "商品管理", 44, null, null, null, null,null));
        /*模拟查询数据库结束*/

        List<Tree<Object>> treeList1 = BuildTreeUtil.buildTree(nodeList1);
        System.out.println(treeList1);
    }
}

functionList.java

/**
 * 有扩展字段则加扩展字段,没有则只需继承TreeNode即可
 */
@Data
public class FunctionList  extends TreeNode {

    private String icon;

    private String path;

    private String desc;

    private Integer level;

    private Integer type;

    /* 方便测试,可不加 */
    public FunctionList(String id, String parentId, String name, Integer weight, String icon, String path, String desc, Integer level, Integer type) {
        this.setId(id);
        this.setName(name);
        this.setParentId(parentId);
        this.setWeight(weight);

        this.icon = icon;
        this.path = path;
        this.desc = desc;
        this.level = level;
        this.type = type;
    }
}