多级菜单 树结构 排序 前端 后端 java
目录
省流:
正文:
v1.0版
前端传的值:
后端代码:
v2.0版
v3.0版
省流:
前端提交过来整个树即可。
给整个树进行sort。代码如下:
public static void sort(List<Node> tree){int i = 0;for (Node o : tree) {o.setSort(i++);if(o.getChild()!=null){sort(o.getChild());}}}
这个只是单纯排序,没有替换parentId。升级版本见正文。
排序完以后,结果如下:
一级节点的sort:1,2,3,4...
二级节点的sort:每个一级节点下的二级节点,都会从1开始排序:1,2,3,4...
|-- 一级节点1|--二级节点1|--二级节点2|--二级节点3
|-- 一级节点2|--二级节点1|--二级节点2|--二级节点3
|-- 一级节点3|--二级节点1|--二级节点2|--二级节点3
正文:
v1.0版
前端传的值:
{"id": "雪花id","parentId": "雪花id","name":"书籍","sort":"1","children": [{"id": "雪花id","parentId": "雪花id","name": "数学","sort": 1,"children": [{"children": [],"id": "雪花id","parentId": "雪花id","name": "几何学","sort": 1,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "代数学","sort": 2,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "概率学","sort": 3,}]},{"id": "雪花id","parentId": "雪花id","name": "物理","sort": 2,"children": [{"children": [],"id": "雪花id","parentId": "雪花id","name": "光学","sort": 1,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "力学","sort": 2,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "量子学","sort": 3,}]},{"id": "雪花id","parentId": "雪花id","name": "化学","sort": 3,"children": [{"children": [],"id": "雪花id","parentId": "雪花id","name": "有机学","sort": 1,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "无机学","sort": 2,},{"children": [],"id": "雪花id","parentId": "雪花id","name": "应用化学","sort": 3,}]}]
}
后端代码:
后端模拟前端传值单元测试:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class SortT1 {public static void main(String[] args) {//一级节点Node firstNode1 = new Node();Node firstNode2 = new Node();Node firstNode3 = new Node();List<Node> first = new ArrayList<>(Arrays.asList(firstNode1,firstNode2,firstNode3));//二级节点Node sec1First1 = new Node();Node sec2First1 = new Node();Node sec3First1 = new Node();List<Node> second1 = new ArrayList<>(Arrays.asList(sec1First1,sec2First1,sec3First1));firstNode1.setChild(second1);Node sec1First2 = new Node();Node sec2First2 = new Node();Node sec3First2 = new Node();List<Node> second2 = new ArrayList<>(Arrays.asList(sec1First2,sec2First2,sec3First2));firstNode2.setChild(second2);Node sec1First3 = new Node();Node sec2First3 = new Node();Node sec3First3 = new Node();List<Node> second3 = new ArrayList<>(Arrays.asList(sec1First3,sec2First3,sec3First3));firstNode3.setChild(second3);sort(first);System.out.println(first);}public static void sort(List<Node> tree){int i = 0;for (Node o : tree) {o.setSort(i++);if(o.getChild()!=null){sort(o.getChild());}}}
}
import java.util.List;public class Node {private Integer sort;private List<Node> child;public Integer getSort() {return sort;}public void setSort(Integer sort) {this.sort = sort;}public List<Node> getChild() {return child;}public void setChild(List<Node> child) {this.child = child;}
}
v2.0版
增加parentId
public static void main(String[] args) {//一级节点Node firstNode1 = new Node("0001");Node firstNode2 = new Node("0002");Node firstNode3 = new Node("0003");List<Node> first = new ArrayList<>(Arrays.asList(firstNode1,firstNode2,firstNode3));//二级节点Node sec1First1 = new Node("00010001");Node sec2First1 = new Node("00010002");Node sec3First1 = new Node("00010003");List<Node> second1 = new ArrayList<>(Arrays.asList(sec1First1,sec2First1,sec3First1));firstNode1.setChild(second1);Node sec1First2 = new Node("00020001");Node sec2First2 = new Node("00020002");Node sec3First2 = new Node("00020003");List<Node> second2 = new ArrayList<>(Arrays.asList(sec1First2,sec2First2,sec3First2));firstNode2.setChild(second2);Node sec1First3 = new Node("00030001");Node sec2First3 = new Node("00030002");Node sec3First3 = new Node("00030003");List<Node> second3 = new ArrayList<>(Arrays.asList(sec1First3,sec2First3,sec3First3));firstNode3.setChild(second3);sort(first, "0");System.out.println(first);}public static void sort(List<Node> tree,String parentId){int i = 0;for (Node o : tree) {o.setSort(i++);o.setParentId(parentId);if(o.getChild()!=null){sort(o.getChild(),o.getId());}}}
public class Node {public Node(String id){this.id = id;}private Integer sort;private List<Node> child;private String id;private String parentId;
//省略了get set方法没写,自己测的时候记得加上
}
v3.0版
保存到数据库:将所有节点都放到一个list里。
public static void main(String[] args) {//省略前面的代码//...List<Node> result = new ArrayList<>();sort(first, "0", result);//将结果集保存到数据库xxxMapper.saveOrUpdate(result);}public static void sort(List<Node> tree,String parentId,List<Node> result){int i = 0;for (Node o : tree) {o.setSort(i++);o.setParentId(parentId);if(o.getChild()!=null){sort(o.getChild(),o.getId(),result);}o.setChild(null);//递归走出来后就不需要child了result.add(o);//将当前节点存到结果集里}}
注意:为了避免意外发生,生产上记得加上深度,以防万一出现死循环导致栈溢出stackoverflow。
===================分割线===================
文章到此已经结束,以下是紫薯布丁
|-- 一级节点1
|--二级节点1
|--二级节点2
|--二级节点3
|-- 一级节点2
|--二级节点1
|--二级节点2
|--二级节点3
|-- 一级节点3
|--二级节点1
|--二级节点2
|--二级节点3
{
"id": "雪花id",
"parentId": "雪花id",
"name":"书籍",
"sort":"1",
"children": [
{
"id": "雪花id",
"parentId": "雪花id",
"name": "数学",
"sort": 1,
"children": [
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "几何学",
"sort": 1,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "代数学",
"sort": 2,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "概率学",
"sort": 3,
}
]
},
{
"id": "雪花id",
"parentId": "雪花id",
"name": "物理",
"sort": 2,
"children": [
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "光学",
"sort": 1,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "力学",
"sort": 2,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "量子学",
"sort": 3,
}
]
},
{
"id": "雪花id",
"parentId": "雪花id",
"name": "化学",
"sort": 3,
"children": [
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "有机学",
"sort": 1,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "无机学",
"sort": 2,
},
{
"children": [],
"id": "雪花id",
"parentId": "雪花id",
"name": "应用化学",
"sort": 3,
}
]
}
]
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SortT1 {
public static void main(String[] args) {
//一级节点
Node firstNode1 = new Node();
Node firstNode2 = new Node();
Node firstNode3 = new Node();
List<Node> first = new ArrayList<>(Arrays.asList(firstNode1,firstNode2,firstNode3));
//二级节点
Node sec1First1 = new Node();
Node sec2First1 = new Node();
Node sec3First1 = new Node();
List<Node> second1 = new ArrayList<>(Arrays.asList(sec1First1,sec2First1,sec3First1));
firstNode1.setChild(second1);
Node sec1First2 = new Node();
Node sec2First2 = new Node();
Node sec3First2 = new Node();
List<Node> second2 = new ArrayList<>(Arrays.asList(sec1First2,sec2First2,sec3First2));
firstNode2.setChild(second2);
Node sec1First3 = new Node();
Node sec2First3 = new Node();
Node sec3First3 = new Node();
List<Node> second3 = new ArrayList<>(Arrays.asList(sec1First3,sec2First3,sec3First3));
firstNode3.setChild(second3);
sort(first);
System.out.println(first);
}
public static void sort(List<Node> tree){
int i = 0;
for (Node o : tree) {
o.setSort(i++);
if(o.getChild()!=null){
sort(o.getChild());
}
}
}
}
public static void main(String[] args) {
List<Node> result = new ArrayList<>();
sort(first, "0", result);
//将结果集保存到数据库
xxxMapper.saveOrUpdate(result);
}
public static void sort(List<Node> tree,String parentId,List<Node> result){
int i = 0;
for (Node o : tree) {
o.setSort(i++);
o.setParentId(parentId);
if(o.getChild()!=null){
sort(o.getChild(),o.getId(),result);
}
o.setChild(null);//递归走出来后就不需要child了
result.add(o);//将当前节点存到结果集里
}
}
public class Node {
public Node(String id){
this.id = id;
}
private Integer sort;
private List<Node> child;
private String id;
private String parentId;
//省略了get set方法没写,自己测的时候记得加上
}
相关文章:
多级菜单 树结构 排序 前端 后端 java
目录 省流: 正文: v1.0版 前端传的值: 后端代码: v2.0版 v3.0版 省流: 前端提交过来整个树即可。 给整个树进行sort。代码如下: public static void sort(List<Node> tree){int i 0;for…...
LAN-Free在数据备份时的应用与优势
在灾备领域中,常见的备份架构有LAN、LAN-Free和Server-Free备份,其中LAN备份架构图见图1,LAN-Free备份架构图见图2,Server-Free备份架构图见图3,途中红色箭头为备份数据流量走向: 图 1 图 2 图 3 从图1、图…...
HTML 文档声明和语言设置
HTML 文档声明 DOCTYPE 文档类型声明,用于告诉浏览器的解析器,该以那种 HTML 版本来解析这个文件。 HTML 5 版本声明 <!DOCTYPE html>XHTML 1.0 严格版声明 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http:/…...
【C++基础知识学习笔记】精华版(复习专用)
常用语法 函数重载(Overload) 规则: 函数名相同 参数个数不同、参数类型不同、参数顺序不同 注意: 返回值类型与函数重载无关 调用函数时,实参的隐式类型转换可能会产生二义性 默认参数 C++ 允许函数设置默认参数,在调用时可以根据情况省略实参。规则如下: 默认参数只能…...
探索ChatGPT在学术写作中的应用与心得
随着人工智能的迅猛发展,ChatGPT作为一种强大的自然语言处理模型,逐渐在学术界引起了广泛的关注。本文将探讨ChatGPT在学术写作中的应用,并分享使用ChatGPT进行学术写作时的一些经验和心得。 01 — ChatGPT在学术写作中的应用 1.文献综述和…...
Android:怎么学习才能更好的进大厂呢?
怎么学习才能更好的进大厂呢? 很多朋友都在问这个问题。 其实没有什么特别的技巧,就是依靠自己的毅力和决心。一天做不到,就一个月;一个月做不到,就一年。只要有决心,无论学历或资历如何,都不是…...
CSS标点符号换行问题
最近遇到一个奇怪的现象,元素中中文文本正常显示,但是加了一堆符号后中文文本居然换行了. div{width: 200px;border: 1px solid blue;word-break: break-all;} <div>文本</div>经过研究发现,因为标点符号不允许出现在行首和行尾,连带着符号…...
jdbc Preparestatement防止SQL注入的原理
2023-10-28T03:37:11.264132Z 2 Execute select * from users where username liulemon and password \ or \1\ 1\ 可以看到这一行,预编译时?变成了转义字符 useServerPrepStmtstrue加上这句才能预编译...
如何控制 LLM 的输出格式和解析其输出结果?
现在很多人对于如何使用像 ChatGPT 这样的 LLM 已经比较有经验了,可以使用各种不同的 Prompt 得到自己想要的结果。但有时候我们的使用场景不局限于手动操作,而是需要结合程序去调用 API,并且解析 API 的返回结果,从而实现一些自动…...
【Linux】 ps 命令使用
ps (英文全拼:process status)命令用于显示当前进程的状态,类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…...
C++二分查找算法的应用:长度递增组的最大数目
本文涉及的基础知识点 二分查找 题目 给你一个下标从 0 开始、长度为 n 的数组 usageLimits 。 你的任务是使用从 0 到 n - 1 的数字创建若干组,并确保每个数字 i 在 所有组 中使用的次数总共不超过 usageLimits[i] 次。此外,还必须满足以下条件&…...
提示3D标题编辑器仍在运行怎么解决,以及3D标题编辑器怎么使用
在进行视频剪辑时,尤其是剪辑一些带有文字的开场视频,一般都会使用具有立体效果的3D标题,这样制作出来的视频效果不仅好看,还非常的炫酷,但是对于一些刚刚开始接触视频剪辑的小伙伴来说,可能对3D标题还不是…...
1. PPT高效初始化设置
1. PPT高效初始化设置 软件安装:Office 2019 主题和颜色 颜色可以在白天与黑夜切换,护眼 切换成了黑色 撤回次数 撤回次数太少,只有20次怎么办 自动保存 有时忘记保存就突然关闭,很需要一个自动保存功能 图片压缩 图…...
el-cascader级联选择器选中一个全选中问题
问题 只选中一个却把同级全选中 解决 :props中添加label、value、children属性 label、value、children属性值需要和后端返回的集合中的字段名保持一致 后端返回数据:...
Opencascad(C++)-创建自定义坐标系
文章目录 1、前言2、在Opencascad中显示小的坐标系3、在Opencascad中创建自定义的坐标系 1、前言 在Opencascad开发时,在view中可以显示小的坐标系,但是有时我们需要在建模时创建基准坐标系,当然可以作为工件坐标系也可以作为基准坐标系。本…...
MySQL数据库入门到大牛_01_数据库概述
文章目录 1. 为什么要使用数据库2. 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库与数据库管理系统的关系2.3 常见的数据库管理系统排名(DBMS)2.4 常见的数据库介绍 3. MySQL介绍3.1 概述3.2 MySQL发展史重大事件3.3 关于MySQL 8.03.4 Why choose MySQL?3.5 Oracle v…...
Web - Servlet详解
目录 前言 一 . Servlet简介 1.1 动态资源和静态资源 1.2 Servlet简介 二 . Servlet开发流程 2.1 目标 2.2 开发过程 三 . Servlet注解方式配置 编辑 四 . servlet生命周期 4.1 生命周期简介 4.2 生命周期测试 4.3 生命周期总结 五 . servlet继承结构 5.1 ser…...
postgresql 触发器如何生成递增序列号,从1开始,并且每天重置
大家好,我是三叔,许久不见,这期给大家介绍一下笔者在开发中遇到的业务处理:pgsql 创建触发器生成每日递增序列,并且第二天重置,根据不同的用户进行不同的控制。 1.创建生成递增序列的 table 表 -- 创建us…...
“第五十九天”
这是昨天那道题,这个后面自己的处理思路还是差了点,这道题关键感觉就是对进位的处理的,由于进位的存在,所以处理数据的时候只能从最低位开始,我一开始是从高位处理的,而且后面越来越迷,这个点一…...
IDEA集成Docker插件打包服务镜像与运行【附Docker命令汇总】
Docker官网 Docker官网:https://www.docker.com/ Docker Hub官网:http://hub.docker.com/ 什么是Docker Docker 是一个开源的容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者和系统管理员在笔记本上编…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
