个人技术分享

Java通用三级菜单工具类

通常在写三级菜单时会使用递归方式去写,但是时间长了会发现很多重复的代码一直在写,改,也就改几个名字。

实现方式

抽象属性结构

常用的三个字段,子级id、父级id、其次是数组children。

将返回对象或者是三级菜单对象实现这个类。

import java.util.List;

public interface AbstractTreeNode {
    // 子级id
    Long getId();

    // 父级id
    Long getParentId();

    // 子级数组
    void setChildren(List<? extends AbstractTreeNode> children);
}
代码示例
import cn.bunny.tree.AbstractTreeNode;
import lombok.Data;

import java.util.List;

@Data
public class ForumBoardVo implements AbstractTreeNode {
    private Long id;
    // 父级板块ID
    private Long parentId;
    // 板块名
    private String boardName;
    // 封面
    private String cover;
    // 描述
    private String boardDesc;
    // 排序
    private Integer sort;
    // 0:只允许管理员发帖 1:任何人可以发帖
    private Boolean postType;
    private List<ForumBoardVo> children;

    @Override
    public void setChildren(List<? extends AbstractTreeNode> children) {
        this.children = (List<ForumBoardVo>) children;
    }
}

构建树型结构

import java.util.ArrayList;
import java.util.List;

public class TreeBuilder<T extends AbstractTreeNode> {
    /**
     * 构建属性结构
     *
     * @param nodeList 需要构建的数组
     * @return 树型结构
     */

    public List<T> buildTree(List<T> nodeList) {
        List<T> tree = new ArrayList<>();
        for (T node : nodeList) {
            if (node.getParentId() == 0) {
                node.setChildren(getChildren(node.getId(), nodeList));
                tree.add(node);
            }
        }
        return tree;
    }

    /**
     * 递归设置子级菜单
     *
     * @param nodeId   节点id
     * @param nodeList 节点列表
     * @return 子级菜单
     */
    private List<T> getChildren(Long nodeId, List<T> nodeList) {
        List<T> children = new ArrayList<>();
        for (T node : nodeList) {
            if (node.getParentId().equals(nodeId)) {
                node.setChildren(getChildren(node.getId(), nodeList));
                children.add(node);
            }
        }
        return children;
    }
}
使用方式

先向正常的返回数组使用,毕竟我们是要返回VO对象,如果是直接返回数据库中对象也可,下面只做一个示例。

public List<ForumBoardVo> loadBoard() {
    // 数据库中list
    List<ForumBoard> forumBoardListDB = list();
    // 构建返回对象数组
    List<ForumBoardVo> forumBoardVoList = new ArrayList<>();
    // 树型结构返回数组
    TreeBuilder<ForumBoardVo> treeBuilder = new TreeBuilder<>();

    // 对数据库中数组进行排序,这个可有可无
    forumBoardListDB.sort(Comparator.comparing(ForumBoard::getSort));
    // 将数据库中数组一个一个塞到 List<ForumBoardVo> 的数组中
    forumBoardListDB.forEach(forumBoard -> {
        ForumBoardVo forumBoardVo = new ForumBoardVo();
        BeanUtils.copyProperties(forumBoard, forumBoardVo);

        forumBoardVoList.add(forumBoardVo);
    });

    // 最后将调用树形结构对象,构建树型结构。
    return treeBuilder.buildTree(forumBoardVoList);
}