【项目】Java树形结构集合分页,java对list集合进行分页
Java树形结构集合分页
- 需求
- 难点
- 实现
- 第一步:查出所有树形集合数据 (需进行缓存处理)
- selectTree 方法步骤:
- TreeUtil类:
- 第二步:分页 GoodsCategoryController
- 分页
- getGoodsCategoryTree方法步骤:
- 第三步:前端实现
- 效果图:
需求
商品类目树数据量大导致加载太慢,需添加一个分页功能。
难点
- 树状结构不能用mybatis-plus自带的分页功能,需自己写分页逻辑
- 因数据量大,需进行缓存处理
实现
第一步:查出所有树形集合数据 (需进行缓存处理)
List<GoodsCategoryTree> resultList = goodsCategoryService.selectTree(null);
List<GoodsCategoryTree> selectTree(GoodsCategory goodsCategory);
selectTree 方法步骤:
判断key是否存在,如果存在,直接取缓存的值 ,不存在就从数据库查出数据,并把值存到redis里。
@Overridepublic List<GoodsCategoryTree> selectTree(GoodsCategory goodsCategory) {if(redisTemplate.hasKey(CacheConstants.GOODS_CATEGORY_TREE_KEY)){log.info("商品类目管理 selectTree cache");List<GoodsCategoryTree> cacheList = SpringUtils.getBean(RedisCache.class).getCacheList(CacheConstants.GOODS_CATEGORY_TREE_KEY);return cacheList;}log.info("商品类目管理 selectTree db");List<GoodsCategoryTree> treeList = getTree(this.list(Wrappers.lambdaQuery(goodsCategory)));if (CollUtil.isNotEmpty(treeList)){SpringUtils.getBean(RedisCache.class).setCacheList(CacheConstants.GOODS_CATEGORY_TREE_KEY,treeList);}return treeList;}
其中 getTree()如下:
/*** @Description: 构建树*/private List<GoodsCategoryTree> getTree(List<GoodsCategory> entitys) {List<GoodsCategoryTree> treeList = entitys.stream().filter(entity -> !entity.getId().equals(entity.getParentId())).sorted(Comparator.comparingInt(GoodsCategory::getSort)).map(entity -> {GoodsCategoryTree node = new GoodsCategoryTree();BeanUtil.copyProperties(entity, node);return node;}).collect(Collectors.toList());return TreeUtil.build(treeList, CommonConstants.PARENT_ID);}
TreeUtil类:
@UtilityClass
public class TreeUtil {/*** 两层循环实现建树** @param treeNodes 传入的树节点列表* @return*/public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) {List<T> trees = new ArrayList<>();for (T treeNode : treeNodes) {if (root.equals(treeNode.getParentId())) {trees.add(treeNode);
// trees.sort(Comparator.comparing(TreeNode::getSort));}for (T it : treeNodes) {if (it.getParentId().equals(treeNode.getId())) {treeNode.addChildren(it);
// treeNode.getChildren().sort(Comparator.comparing(TreeNode::getSort));}}}return trees;}
}
第二步:分页 GoodsCategoryController
/*** 返回树形集合分页数据** @return*/@ApiOperation(value = "返回树形集合分页数据")@GetMapping("/treePage")public R getGoodsCategoryTree(Page page, GoodsCategory goodsCategory) {//得到所有数据List<GoodsCategoryTree> resultList = goodsCategoryService.selectTree(null);if (resultList != null && resultList.size() > 0) {page.setTotal(resultList.size());}//分页List<GoodsCategoryTree> finalList = goodsCategoryService.getFinalListByPage(page,resultList);if (finalList != null && finalList.size() > 0) {page.setRecords(finalList);}return R.ok(page);}
分页
/** 分页查询类目树*/List<GoodsCategoryTree> getFinalListByPage(Page page , List<GoodsCategoryTree> resultList );
getGoodsCategoryTree方法步骤:
参考:java对list集合进行分页
首先把数据根据创建时间倒序排列,再进行分页
@Overridepublic List<GoodsCategoryTree> getFinalListByPage(Page page, List<GoodsCategoryTree> resultList) {//根据创建时间倒序排列List<GoodsCategoryTree> treeList = resultList.stream().sorted(Comparator.comparing(GoodsCategoryTree::getCreateTime).reversed()).collect(Collectors.toList());//进行分页List<GoodsCategoryTree> subList = treeList.stream().skip((page.getCurrent()-1)*page.getSize()).limit(page.getSize()).collect(Collectors.toList());return subList;}
第三步:前端实现
avue-crud 组件加上:page.sync=“page”
<avue-crudref="crud":data="tableData":page.sync="page":permission="permissionList":table-loading="tableLoading":option="tableOption":before-open="beforeOpen"v-model="form"@on-load="getPage"@refresh-change="refreshChange"@row-update="handleUpdate"@row-save="handleSave"@row-del="handleDel">
data() 加上:
page: {total: 0, // 总页数currentPage: 1, // 当前页数pageSize: 20, // 每页显示多少条ascs: [], //升序字段descs: "create_time", //降序字段},paramsSearch: {},date: [],};
重写getPage()方法:
getPage(page, params) {this.tableLoading = true;fetchTree(Object.assign({current: page.currentPage,size: page.pageSize,descs: this.page.descs,ascs: this.page.ascs,beginTime: this.date[0],endTime: this.date[1],},params,this.paramsSearch)).then((response) => {let tableData = response.data.data.records;this.tableData = tableData;this.page.total = response.data.data.total;this.page.currentPage = page.currentPage;this.page.pageSize = page.pageSize;let parentIdDIC = [{id: "0",name: "顶级分类",parentId: "0",},];tableData.forEach((item) => {parentIdDIC.push({id: item.id,name: item.name,parentId: item.parentId,});});this.$refs.crud.DIC.parentId = parentIdDIC;this.tableLoading = false;}).catch(() => {this.tableLoading = false;});},
效果图:
相关文章:

【项目】Java树形结构集合分页,java对list集合进行分页
Java树形结构集合分页需求难点实现第一步:查出所有树形集合数据 (需进行缓存处理)selectTree 方法步骤:TreeUtil类:第二步:分页 GoodsCategoryController分页getGoodsCategoryTree方法步骤:第三…...

java.lang.IllegalArgumentException: itemView may not be null
报错截图:场景介绍:在使用recycleView 自动递增数据,且自动滚动到最新行; 当数据达到273条 时出现ANR;项目中 全部的列表适配器使用的三方库:BaseRecyclerViewAdapterHelper (很早之前的项目&am…...

[ 攻防演练演示篇 ] 利用 shiro 反序列化漏洞获取主机权限
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

达人合作加持品牌布局,3.8女神玩转流量策略!
随着迅猛发展的“她经济”,使社区本就作为内容种草的平台,自带“营销基因”。在3.8女神节即将到来之际,如何充分利用平台女性资源优势,借助达人合作等手段,实现迅速引流,来为大家详细解读下。一、小红书节日…...

观点丨Fortinet谈ChatGPT火爆引发的网络安全行业剧变
FortiGuard报告安全趋势明确指出“网络攻击者已经开始尝试AI手段”,ChatGPT的火爆之际的猜测、探索和事实正在成为这一论断的佐证。攻守之道在AI元素的加持下也在悄然发生剧变。Fortinet认为在攻击者利用ChatGPT等AI手段进行攻击的无数可能性的本质,其实…...

工业企业用电损耗和降损措施研究
来自用电设备和供配电系统的电能损耗。而供配电系统的电能损耗,包括企业变配电设备、控制设备企业在不断降低生产成本,追求经济效益的情况下,进一步降低供配电系统中的电能损耗,使电气设摘要:电网电能损耗是一个涉及面很广的综合性问题,主要包括管理损耗和技术损耗两部分…...
高并发、高性能、高可用
文章目录一、高并发是什么?二、 高性能是什么三、 高可用什么是一、高并发是什么? 示例:高并发是现在互联网分布式框架设计必须要考虑的因素之一,它是可以保证系统能被同时并行处理很多请求,对于高并发来说࿰…...

剑指 Offer 62. 圆圈中最后剩下的数字
摘要 剑指 Offer 62. 圆圈中最后剩下的数字 一、约瑟夫环解析 题目中的要求可以表述为:给定一个长度为 n 的序列,每次向后数 m 个元素并删除,那么最终留下的是第几个元素?这个问题很难快速给出答案。但是同时也要看到ÿ…...

概率论小课堂:高斯分布(正确认识大概率事件)
文章目录 引言I 预备知识1.1 正态分布1.2 置信度1.3 风险II 均值、标准差和发生概率三者的关系。2.1 “三∑原则”2.2 二班成绩比一班好的可能性2.3 减小标准差引言 泊松分布描述的是概率非常小的情况下的统计规律性。学习高斯分布来正确认识大概率事件,随机变量均值的差异和偶…...

剑指 Offer 43. 1~n 整数中 1 出现的次数
摘要 剑指 Offer 43. 1~n 整数中 1 出现的次数 一、数学思维解析 将1~ n的个位、十位、百位、...的1出现次数相加,即为1出现的总次数。 设数字n是个x位数,记n的第i位为ni,则可将n写为 nxnx−1⋯n2n1: 称" …...

如何成为程序员中的牛人/高手?
目录 一、牛人是怎么成为牛人的? 二、关于牛人的一点看法 三、让程序员与业务接壤,在开发团队中“升级” 四、使用低代码平台 目标效果 五、最后 祝伟大的程序员们梦想成真、码到成功! 一、牛人是怎么成为牛人的? 最近在某…...

云原生时代顶流消息中间件Apache Pulsar部署实操之轻量级计算框架
文章目录Pulsar Functions(轻量级计算框架)基础定义工作流程函数运行时处理保证和订阅类型窗口函数定义窗口类型滚动窗口滑动窗口函数配置函数示例有状态函数示例窗口函数示例自定义函数开发定义原生语言接口示例Pulsar函数SDK示例Pulsar Functions(轻量级计算框架) 基础定义 …...

数据结构刷题(十九):77组合、216组合总和III
1.组合题目链接过程图:先从集合中取一个数,再依次从剩余数中取k-1个数。思路:回溯算法。使用回溯三部曲进行解题:递归函数的返回值以及参数:n,k,startIndex(记录每次循环集合从哪里开始遍历的位…...

PyQt 做美*女GIF设置桌面,每天都很爱~
人生苦短,我用python 要说程序员工作的最大压力不是来自于工作本身, 而是来自于需要不断学习才能更好地完成工作, 因为程序员工作中面对的编程语言是在不断更新的, 同时还要学习熟悉其他语言来提升竞争力… 好了,学习…...
[渗透测试笔记] 54.日薪2k的蓝队hw中级定级必备笔记系列篇3之域渗透黄金票据和白银票据
前文链接 [渗透测试笔记] 52.告别初级,日薪2k的蓝队hw中级定级必备笔记 [渗透测试笔记] 53.日薪2k的蓝队hw中级定级必备笔记2 文章目录 Kerberos认证协议NTLM认证协议Kerberos和NTLM比较黄金票据原理黄金票据条件复现过程白银票据原理白银票据条件复现过程黄金票据和白银票据…...
【异常】Spring Cloud Gateway网关自定义过滤器无法获取到请求体body的内容?不存在的!
一、需求说明 项目要使用到网关SpringCloud Gateway进行验签,现在定义了一个过滤器ValidateSignFilter, 我希望,所以过网关SpringCloud Gateway的请求,都能够校验一下请求头,看看是否有Sign这个字段放在请求头中。 二、异常说明 但是,我遇到了SpringCloud Gateway网关…...
CNN 卷积神经网络对染色血液细胞分类(blood-cells)
目录 1. 介绍 2. 加载数据 3. 可视化 3.1 显示单幅图像 3.2 显示多幅图像...

Kubernetes学习(三)Service
Service对象 为什么需要Service 每个Pod都有自己的IP地址,但是在Deployment中,在同一时刻运行的Pod集合可能与稍后运行该应用程序的Pod集合不同。 这就导致了一个问题:如果一组Pod(称为后端)为集群内其他Pod&#x…...
数学小课堂:古德-图灵折扣估计法和插值法(防范黑天鹅事件的方法)
文章目录 引言I 黑天鹅事件产生的原因1.1 置信度1.2 数据的稀疏性1.3 零概率问题II 防范黑天鹅事件的方法2.1 古德-图灵折扣估计法2.2 插值法引言 防范黑天鹅事件的方法 古德-图灵折扣估计法:它主要是解决零概率的事件古德的方法虽然解决了零概率的问题,但是依然没有解决数据…...
redis getshell方法
前言 参考文章 https://paper.seebug.org/1169 https://blog.csdn.net/weixin_55843787/article/details/123829606 https://blog.csdn.net/chenglanqi6606/article/details/100909518 Redis是什么 Redis是一款基于键值对的NoSQL数据库,它的值支持多种数据结构 …...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...