树型结构构建,模糊查询,过滤

2024-02-02 12:44

本文主要是介绍树型结构构建,模糊查询,过滤,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

1、最近在做甘特图,有些需求和树型结构要求很大,看的是 pingCode,有搜索

在这里插入图片描述
2、还有抽取一部分树型结构的,如下是抽取上面的结构类型为需求的,重新组成树型

在这里插入图片描述

二、构建多颗树型结构

1、某些业务下,从数据库查询出来一堆数据后,希望构建树型结构,但是存在一种情况就是,可能这堆数据不是完整的,比如如下情况,我查询出来了除了D节点外的所有数据,那么这种情况下,如果使用正常的构建方式,那么构建出来的数据会丢失数据H,I,J,M,即使这四个节点的数据已经查询出来了,但是因为D节点缺失,导致无法链接上,如果是中间断开了,那断开的部分单独成一个树型结构
在这里插入图片描述

2、那有人说这不是正常的吗,你为啥D节点不查询出来,一颗完整的树是这样的啊,但是存在一些业务情况如下,上述的数据中除了D节点,其它节点的类型都是type1,而D节点的Type 是2,我现在就是想看type为1的,然后你给我形成树型结构

3、代码如下,其中模拟的时候,缺失节点999,所以结果如下,把节点999那一条结构,单独做一个树型结构返回,避免丢失
在这里插入图片描述

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;import java.util.*;
import java.util.stream.Collectors;class ChildHandle {public static void main(String[] args) {List<Node> mockData = mockData();List<List<Node>> lists = buildTree(mockData, 50);System.out.println(JSON.toJSONString(lists));}public static List<List<Node>> buildTree(List<Node> data, int maxDepth) {List<List<Node>> multipleTopNodeTreeResult = new ArrayList<>();if (CollUtil.isEmpty(data)) {return multipleTopNodeTreeResult;}Map<Integer, List<Node>> moduleMap = new HashMap<>(32);// 找出所有的父节点,因为有些数据并不是一个完整的树型树,如果是中间断开了,那断开的部分单独成一个树型结构HashSet<Integer> rootIds = new HashSet<>();Set<Integer> allIds = data.stream().map(Node::getId).collect(Collectors.toSet());for (Node module : data) {moduleMap.putIfAbsent(module.getPid(), new ArrayList<>());moduleMap.get(module.getPid()).add(module);// 当前的item的pid对应的数据不存在,说明从当前的item的pid就断开了,则为这个pid单独起一颗树if (!allIds.contains(module.getPid())) {rootIds.add(module.getPid());}}// 根据上述的判断,已经知道存在几颗树,则为每颗树构建结构rootIds.forEach(curTopNodeId -> {// 处理每一颗树List<Node> treeInCurTopNode = moduleMap.get(curTopNodeId);if (treeInCurTopNode != null) {// Sort root modulestreeInCurTopNode.sort(Comparator.comparingInt(Node::getSerialNumber));for (Node rootModule : treeInCurTopNode) {buildChildren(rootModule, moduleMap, 0, maxDepth);}} else {treeInCurTopNode = new ArrayList<>();}multipleTopNodeTreeResult.add(treeInCurTopNode);});return multipleTopNodeTreeResult;}private static void buildChildren(Node parentModule, Map<Integer, List<Node>> moduleMap, int depth, int maxDepth) {if (depth >= maxDepth) {// 达到深度限制,停止递归return;}List<Node> children = moduleMap.get(parentModule.getId());if (children != null) {// Sort childrenchildren.sort(Comparator.comparingInt(Node::getSerialNumber));parentModule.setChildren(children);for (Node child : children) {// 增加深度计数 限制最多递归多少次,避免OOMbuildChildren(child, moduleMap, depth + 1, maxDepth);}}}/*** 模拟数据** @return*/private static List<Node> mockData() {List<Node> result = new ArrayList<>();result.add(new Node(1, 0, "Root1"));result.add(new Node(2, 1, "Root1 A"));result.add(new Node(3, 1, "Root1 B"));result.add(new Node(4, 2, "Root1 A.1"));result.add(new Node(5, 2, "Root1 A.2"));result.add(new Node(6, 3, "Root1 B.1"));result.add(new Node(7, 3, "Root1 B.2"));result.add(new Node(8, 3, "Root1 C"));result.add(new Node(9, 8, "Root1 D"));result.add(new Node(1000, 0, "Root2"));result.add(new Node(1001, 1000, "Root2 A"));result.add(new Node(1002, 1000, "Root2 B"));return result;}
}class Node {private Integer id;/*** 父id,为0时说明自己就是第一层*/private Integer pid;/*** 名称*/private String name;/*** 排序*/private int serialNumber;/*** 子集*/private List<Node> children;public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Node> getChildren() {return children;}public void setChildren(List<Node> children) {this.children = children;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public int getSerialNumber() {return serialNumber;}public void setSerialNumber(int serialNumber) {this.serialNumber = serialNumber;}public Node(Integer id, Integer pid, String name) {this.id = id;this.pid = pid;this.name = name;}public Node(Integer id, Integer pid, String name, int serialNumber, List<Node> children) {this.id = id;this.pid = pid;this.name = name;this.serialNumber = serialNumber;this.children = children;}
}

三、树型结构查询过滤

1、方法如下,其中存在一种情况就是查询到父节点满足过滤条件后,那么需不需要判断其子节点是否满足条件,如果不需要注释那段代码即可,如果需要接着往下判断则需要加上

/*** 树型查询** @param tree          树型集合* @param key           搜索的字段名称* @param value         搜索的值* @param childNodeName 子节点名称* @param <T>           数据具体对象* @return tree*/public <T> List<T> filterTree(List<T> tree, Function<JSONObject, Boolean> filterCondition, String childNodeName) {// 这个方法的原始文章 https://blog.csdn.net/weixin_44748212/article/details/131692471// 如果要保留子节点的话把注释的(// 去除子节点start - end )这段代码删掉即可if (CollUtil.isEmpty(tree)) {return new ArrayList<>();}
//        JSONArray arr = JSONArray.parseArray(JSON.toJSONString(tree)); //如果直接序列化,时间格式是 时间戳了JSONArray arr = JSONArray.parseArray(JSON.toJSONStringWithDateFormat(tree, DatePattern.NORM_DATETIME_PATTERN));JSONArray result = filterTree(arr, filterCondition, childNodeName);Type listType = new TypeReference<List<T>>() {}.getType();return JSON.parseObject(result.toJSONString(), listType);}private JSONArray filterTree(JSONArray tree, Function<JSONObject, Boolean> filterCondition, String childNodeName) {Iterator<Object> it = tree.iterator();while (it.hasNext()) {JSONObject current = (JSONObject) it.next();// 把当前节点给到外部,让外部判断是否满足条件if (Boolean.TRUE.equals(filterCondition.apply(current))) {// 去除子节点 startJSONArray childNodes = current.getJSONArray(childNodeName);if (!CollUtil.isEmpty(childNodes)) {JSONArray filterTree = filterTree(childNodes, filterCondition, childNodeName);if (CollUtil.isEmpty(filterTree)) {current.put(childNodeName, new JSONArray());}}// 去除子节点 endcontinue;}JSONArray childNodes = current.getJSONArray(childNodeName);if (!CollUtil.isEmpty(childNodes)) {filterTree(childNodes, filterCondition, childNodeName);}if (CollUtil.isEmpty(childNodes)) {it.remove();}}return tree;}

2、使用方式

List<ListDto> curTreeFilterResult = filterTree(curTree, currentNode -> {String titleValue = currentNode.getString("title");int serialNumber = currentNode.getIntValue("serialNumber");return StrUtil.contains(titleValue, params.getQuery())|| StrUtil.contains(dbDevmProjectInfo.getIdentifier().concat("-" + serialNumber), params.getQuery());}, "children");if (CollUtil.isNotEmpty(curTreeFilterResult)) {filterTreeResult.add(curTreeFilterResult);}

这篇关于树型结构构建,模糊查询,过滤的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/670746

相关文章

一文教你Java如何快速构建项目骨架

《一文教你Java如何快速构建项目骨架》在Java项目开发过程中,构建项目骨架是一项繁琐但又基础重要的工作,Java领域有许多代码生成工具可以帮助我们快速完成这一任务,下面就跟随小编一起来了解下... 目录一、代码生成工具概述常用 Java 代码生成工具简介代码生成工具的优势二、使用 MyBATis Gen

Python+PyQt5实现文件夹结构映射工具

《Python+PyQt5实现文件夹结构映射工具》在日常工作中,我们经常需要对文件夹结构进行复制和备份,本文将带来一款基于PyQt5开发的文件夹结构映射工具,感兴趣的小伙伴可以跟随小编一起学习一下... 目录概述功能亮点展示效果软件使用步骤代码解析1. 主窗口设计(FolderCopyApp)2. 拖拽路径

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

基于Redis实现附近商铺查询功能

《基于Redis实现附近商铺查询功能》:本文主要介绍基于Redis实现-附近商铺查询功能,这个功能将使用到Redis中的GEO这种数据结构来实现,需要的朋友可以参考下... 目录基于Redis实现-附近查询1.GEO相关命令2.使用GEO来实现以下功能3.使用Java实现简China编程单的附近商铺查询4.Red

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

mysql递归查询语法WITH RECURSIVE的使用

《mysql递归查询语法WITHRECURSIVE的使用》本文主要介绍了mysql递归查询语法WITHRECURSIVE的使用,WITHRECURSIVE用于执行递归查询,特别适合处理层级结构或递归... 目录基本语法结构:关键部分解析:递归查询的工作流程:示例:员工与经理的层级关系解释:示例:树形结构的数

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

MySQL 复合查询案例详解

《MySQL复合查询案例详解》:本文主要介绍MySQL复合查询案例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录基本查询回顾多表笛卡尔积子查询与where子查询多行子查询多列子查询子查询与from总结合并查询(不太重要)union基本查询回顾查询