当前位置: 首页 > article >正文

有关自连接表的统一封装

表结构

在这里插入图片描述

RecursionBean

@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class RecursionBean<T>  extends BaseVO {
    /**
     * 编号
     */
    private T id;

    /**
     * 父权限ID,根节点的父权限为空
     * 注释掉@JsonIgnore,是为了前端判断是否是顶级节点,顶级节点才能添加子节点
     */
//    @JsonIgnore
    private T pid;

    private List<? extends RecursionBean<T>> children;

}

封装从服务器端返回的树形数据:RecursionItem

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RecursionItem<T> extends RecursionBean<T> {

    /**
     * 名称
     */
    private String name;

    public RecursionItem(T id, String name) {
        super.setId(id);
        this.name = name;
    }

    public RecursionItem(T id, String name, List<? extends RecursionBean<T>> children) {
        super.setId(id);
        this.name = name;
        super.setChildren(children);
    }
}

工具类

public class RecursionBeanUtil {
    /**
     * 递归查询子节点
     *
     * @param root 根节点
     * @param list 所有节点
     * @return 根节点信息
     */
    private static <E, T extends RecursionBean<E>> List<T> getChildren(T root, List<T> list) {
        final List<T> res = new ArrayList<>();
        for (T item : list) {
            if (Objects.equals(item.getPid(), root.getId())) {
                item.setChildren(getChildren(item, list));
                res.add(item);
            }
        }
        return res;
    }


    public static <E, T extends RecursionBean<E>> List<T> getRecursionList(List<T> list) {
        if (CollectionUtil.isEmpty(list)) {
            return list;
        }

        // 所有的节点
        final List<E> allList = list.stream()
                .map(T::getId)
                .toList();

        // 顶级节点(父ID为空)
        final List<E> topList = list.stream()
                .filter(item -> item.getPid() == null)
                .map(T::getId)
                .toList();

        // 父级节点(不包含在已有父级列表中的新PID)
        final List<E> parentList = list.stream()
                .map(T::getPid)
                .filter(itemPid -> !topList.contains(itemPid))
                .distinct()
                .toList();

        // 叶子节点(非顶级且不在父级列表中的节点ID)
        final List<E> leafList = allList.stream()
                .filter(id -> !topList.contains(id))
                .filter(id -> !parentList.contains(id))
                .toList();

        final List<T> res = new ArrayList<>();
        boolean topFlag = true;
        // 如果待处理集合中顶级节点
        for (T item : list) {
            if (item.getPid() == null) {
                topFlag = false;
                item.setChildren(getChildren(item, list));
                res.add(item);
            }
        }
        if (!topFlag) {
            return res;
        }
        boolean parentFlag = true;
        //如果待处理集合中没有顶级节点但有父节点
        for (T item : list) {
            // 是父节点但不是叶子节点
            if (parentList.contains(item.getPid()) && !leafList.contains(item.getId())) {
                item.setChildren(getChildren(item, list));
                parentFlag = false;
                res.add(item);
            }
        }
        if (!parentFlag) {
            return res;
        }
        //如果待处理集合中全部是叶子节点
        for (T item : list) {
            // 是父节点但不是叶子节点
            if (leafList.contains(item.getId())) {
                item.setChildren(getChildren(item, list));
                res.add(item);
            }
        }
        return res;
    }
}

http://www.kler.cn/news/334045.html

相关文章:

  • 基于定制开发与2+1链动模式的商城小程序搭建策略
  • 招联2025校招内推倒计时
  • 如何在电脑上浏览手机界面
  • 【部署项目】禹神:前端项目部署上线笔记
  • 设计模式-模版方法模式
  • No.4 笔记 | 探索网络安全:揭开Web世界的隐秘防线
  • 如何在每台设备上恢复已删除的照片
  • 最新版的dubbo服务调用(用nacos做注册中心用)
  • 【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem:
  • rtmp协议转websocketflv的去队列积压
  • 【2024年最新】基于Spring Boot+vue的旅游管理系统lw+ppt
  • 从一到无穷大 #36 Lindorm 宽表:东西互联,南北互联,AI一体
  • 真正的Open AI ——LLaMA颠覆开源大模型
  • LeetCode hot100---二叉树专题(C++语言)
  • 《python语言程序设计》2018版第8章19题几何Rectangle2D类(下)-头疼的几何和数学
  • 从Rally到Atlassian Cloud:思科Cisco实现云迁移的技术挑战与解决方案
  • 基于keras的停车场车位识别
  • Spring Boot新闻推荐系统:用户体验优化
  • LeetCode 1928.规定时间内到达终点的最小花费:动态规划
  • 【linux】基础IO(下)