突破CRUD | 万能树工具类封装 (2)

从上面的内容我们了解了前端树组件的渲染展现需要后端提供满足需求的数据格式,那么实际上也就决定了树工具类的核心职责就是将一般的数据列表结构转换为树形结构,从而提供给前端使用。

解读上面所述的核心职责,首先一般列表是什么列表,此处我们假设为菜单列表,这就有了第一个类MenuEntity,紧接着是转换,谁转换成谁 ?数据列表转换树结构,树结构本身那应该就是个类,我们暂且叫它 TreeNode,结合我们第一步假设的菜单列表,那实际上就是 List< MenuEntity > 转换为 List < TreeNode > ,如此就得到了第二个类TreeNode,最后还剩转换这个动作谁去做 ? 那就是我们今天的主角 TreeUtil 了。

好,至此,通过分析树工具类的核心职责,我们分析得到了三个类。

MenuEntity

TreeNode

TreeUtil

OK,有了上面的内容那就来个简单的实现。

树节点类

public class TreeNode {
    // 树节点ID
    private String id;
    // 树节点名称
    private String name;
    // 树节点编码
    private String code;
    // 树节点链接
    private String linkUrl;
    // 树节点图标
    private String icon;
    // 父节点ID
    private String parentId;
}

菜单类

public class MenuEntity {
    // 菜单ID
    private String id;
    // 上级菜单ID
    private String pid;
    // 菜单名称
    private String name;
    // 菜单编码
    private String code;
    // 菜单图标
    private String icon;
    // 菜单链接
    private String url;
}

树工具类

public class TreeUtil {

    /**
     * 树构建
     */

    public static List<TreeNode> build(List<TreeNode> treeNodes,Object parentId){
        List<TreeNode> finalTreeNodes = CollectionUtil.newArrayList();
        for(TreeNode treeNode : treeNodes){
            if(parentId.equals(treeNode.getParentId())){
                finalTreeNodes.add(treeNode);
                innerBuild(treeNodes,treeNode);
            }
        }
        return finalTreeNodes;
    }

    private static void innerBuild(List<TreeNode> treeNodes,TreeNode parentNode){
        for(TreeNode childNode : treeNodes){
            if(parentNode.getId().equals(childNode.getParentId())){
                List<TreeNode> children = parentNode.getChildren();
                if(children == null){
                    children = CollectionUtil.newArrayList();
                    parentNode.setChildren(children);
                }
                children.add(childNode);
                childNode.setParentId(parentNode.getId());
                innerBuild(treeNodes,childNode);
            }
        }
    }
}

树工具类实现的两个关键点,第一,树构建的开始位置也就是从哪里开始构建,所以需要一个父ID参数来指定构建的起始位置,第二,构建到什么时候结束,不做限制的的话,我们的树是可以无限延伸的,所以此处innerBuild方法进行递归操作。

测试代码

public static void main(String[] args{
    // 1、模拟菜单数据
    List<MenuEntity> menuEntityList = CollectionUtil.newArrayList();
    menuEntityList.add(new MenuEntity("1","0","系统管理","sys","/sys"));
    menuEntityList.add(new MenuEntity("11","1","用户管理","user","/sys/user"));
    menuEntityList.add(new MenuEntity("111","11","用户添加","userAdd","/sys/user/add"));
    menuEntityList.add(new MenuEntity("2","0","店铺管理","store","/store"));
    menuEntityList.add(new MenuEntity("21","2","商品管理","shop","/shop"));

    // 2、MenuEntity -> TreeNode
    List<TreeNode> treeNodes = CollectionUtil.newArrayList();
    for(MenuEntity menuEntity : menuEntityList){
        TreeNode treeNode = new TreeNode();
        treeNode.setId(menuEntity.getId());
        treeNode.setParentId(menuEntity.getPid());
        treeNode.setCode(menuEntity.getCode());
        treeNode.setName(menuEntity.getName());
        treeNode.setLinkUrl(menuEntity.getUrl());
        treeNodes.add(treeNode);
    }

    // 3、树结构构建
    List<TreeNode> treeStructureNodes = TreeUtil.build(treeNodes,"0");
    Console.log(JSONUtil.formatJsonStr(JSONUtil.toJsonStr(treeStructureNodes)));
}

收工,第一版简单的树工具就实现了。

4、迭代优化 1.0 这不是我的事

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywgfj.html