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

多级菜单 树结构 排序 前端 后端 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

目录 省流&#xff1a; 正文&#xff1a; v1.0版 前端传的值&#xff1a; 后端代码&#xff1a; v2.0版 v3.0版 省流&#xff1a; 前端提交过来整个树即可。 给整个树进行sort。代码如下&#xff1a; public static void sort(List<Node> tree){int i 0;for…...

LAN-Free在数据备份时的应用与优势

在灾备领域中&#xff0c;常见的备份架构有LAN、LAN-Free和Server-Free备份&#xff0c;其中LAN备份架构图见图1&#xff0c;LAN-Free备份架构图见图2&#xff0c;Server-Free备份架构图见图3&#xff0c;途中红色箭头为备份数据流量走向&#xff1a; 图 1 图 2 图 3 从图1、图…...

HTML 文档声明和语言设置

HTML 文档声明 DOCTYPE 文档类型声明&#xff0c;用于告诉浏览器的解析器&#xff0c;该以那种 HTML 版本来解析这个文件。 HTML 5 版本声明 <!DOCTYPE html>XHTML 1.0 严格版声明 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http:/…...

【C++基础知识学习笔记】精华版(复习专用)

常用语法 函数重载(Overload) 规则: 函数名相同 参数个数不同、参数类型不同、参数顺序不同 注意: 返回值类型与函数重载无关 调用函数时,实参的隐式类型转换可能会产生二义性 默认参数 C++ 允许函数设置默认参数,在调用时可以根据情况省略实参。规则如下: 默认参数只能…...

探索ChatGPT在学术写作中的应用与心得

随着人工智能的迅猛发展&#xff0c;ChatGPT作为一种强大的自然语言处理模型&#xff0c;逐渐在学术界引起了广泛的关注。本文将探讨ChatGPT在学术写作中的应用&#xff0c;并分享使用ChatGPT进行学术写作时的一些经验和心得。 01 — ChatGPT在学术写作中的应用 1.文献综述和…...

Android:怎么学习才能更好的进大厂呢?

怎么学习才能更好的进大厂呢&#xff1f; 很多朋友都在问这个问题。 其实没有什么特别的技巧&#xff0c;就是依靠自己的毅力和决心。一天做不到&#xff0c;就一个月&#xff1b;一个月做不到&#xff0c;就一年。只要有决心&#xff0c;无论学历或资历如何&#xff0c;都不是…...

CSS标点符号换行问题

最近遇到一个奇怪的现象,元素中中文文本正常显示,但是加了一堆符号后中文文本居然换行了. div{width: 200px;border: 1px solid blue;word-break: break-all;} <div>文本</div>经过研究发现&#xff0c;因为标点符号不允许出现在行首和行尾&#xff0c;连带着符号…...

jdbc Preparestatement防止SQL注入的原理

2023-10-28T03:37:11.264132Z 2 Execute select * from users where username liulemon and password \ or \1\ 1\ 可以看到这一行&#xff0c;预编译时&#xff1f;变成了转义字符 useServerPrepStmtstrue加上这句才能预编译...

如何控制 LLM 的输出格式和解析其输出结果?

现在很多人对于如何使用像 ChatGPT 这样的 LLM 已经比较有经验了&#xff0c;可以使用各种不同的 Prompt 得到自己想要的结果。但有时候我们的使用场景不局限于手动操作&#xff0c;而是需要结合程序去调用 API&#xff0c;并且解析 API 的返回结果&#xff0c;从而实现一些自动…...

【Linux】 ps 命令使用

ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…...

C++二分查找算法的应用:长度递增组的最大数目

本文涉及的基础知识点 二分查找 题目 给你一个下标从 0 开始、长度为 n 的数组 usageLimits 。 你的任务是使用从 0 到 n - 1 的数字创建若干组&#xff0c;并确保每个数字 i 在 所有组 中使用的次数总共不超过 usageLimits[i] 次。此外&#xff0c;还必须满足以下条件&…...

提示3D标题编辑器仍在运行怎么解决,以及3D标题编辑器怎么使用

在进行视频剪辑时&#xff0c;尤其是剪辑一些带有文字的开场视频&#xff0c;一般都会使用具有立体效果的3D标题&#xff0c;这样制作出来的视频效果不仅好看&#xff0c;还非常的炫酷&#xff0c;但是对于一些刚刚开始接触视频剪辑的小伙伴来说&#xff0c;可能对3D标题还不是…...

1. PPT高效初始化设置

1. PPT高效初始化设置 软件安装&#xff1a;Office 2019 主题和颜色 颜色可以在白天与黑夜切换&#xff0c;护眼 切换成了黑色 撤回次数 撤回次数太少&#xff0c;只有20次怎么办 自动保存 有时忘记保存就突然关闭&#xff0c;很需要一个自动保存功能 图片压缩 图…...

el-cascader级联选择器选中一个全选中问题

问题 只选中一个却把同级全选中 解决 :props中添加label、value、children属性 label、value、children属性值需要和后端返回的集合中的字段名保持一致 后端返回数据&#xff1a;...

Opencascad(C++)-创建自定义坐标系

文章目录 1、前言2、在Opencascad中显示小的坐标系3、在Opencascad中创建自定义的坐标系 1、前言 在Opencascad开发时&#xff0c;在view中可以显示小的坐标系&#xff0c;但是有时我们需要在建模时创建基准坐标系&#xff0c;当然可以作为工件坐标系也可以作为基准坐标系。本…...

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开始,并且每天重置

大家好&#xff0c;我是三叔&#xff0c;许久不见&#xff0c;这期给大家介绍一下笔者在开发中遇到的业务处理&#xff1a;pgsql 创建触发器生成每日递增序列&#xff0c;并且第二天重置&#xff0c;根据不同的用户进行不同的控制。 1.创建生成递增序列的 table 表 -- 创建us…...

“第五十九天”

这是昨天那道题&#xff0c;这个后面自己的处理思路还是差了点&#xff0c;这道题关键感觉就是对进位的处理的&#xff0c;由于进位的存在&#xff0c;所以处理数据的时候只能从最低位开始&#xff0c;我一开始是从高位处理的&#xff0c;而且后面越来越迷&#xff0c;这个点一…...

IDEA集成Docker插件打包服务镜像与运行【附Docker命令汇总】

Docker官网 Docker官网&#xff1a;https://www.docker.com/ Docker Hub官网&#xff1a;http://hub.docker.com/ 什么是Docker Docker 是一个开源的容器引擎&#xff0c;可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者和系统管理员在笔记本上编…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...