Java递归/遍历,实现遍历父子级菜单

目录

准备工作

迭代实现

递归实现

未带有显示顺序的递归遍历


准备工作

create table dormitory_management.fuzi
(
    menu_id       bigint auto_increment comment '菜单ID'
        primary key,
    menu_name     varchar(50)      not null comment '菜单名称',
    parent_id     bigint default 0 null comment '父菜单ID',
    display_order int    default 0 null comment '显示顺序'
);

-- 添加中文测试数据
INSERT INTO dormitory_management.fuzi (menu_name, parent_id, display_order) VALUES
('顶级菜单1', 0, 1),
('顶级菜单2', 0, 2),
('子菜单1-1', 1, 1),
('子菜单1-2', 1, 2),
('子菜单2-1', 2, 1);
@Data
@ToString
public class Fuzi {
    private Long menuId;
    private String menuName;
    private Long parentId;
    private Long  displayOrder;
    private List children; // 子菜单列表
}

迭代实现

分析图:


//Service层
public interface FuziService extends IService {
    List getFuziMenuTreeWithoutChildren();

    List buildMenuTree(List menuList);
}
package com.lyh.mp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyh.mp.entity.Fuzi;
import com.lyh.mp.mapper.FuziMapper;
import com.lyh.mp.service.FuziService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Mtz
 * @version 1.0
 * @2024/2/2015:49
 * @function
 * @comment
 */
@Service
public class FuziServiceImpl extends ServiceImpl implements FuziService {


    @Autowired
    private FuziMapper fuziMapper;


    public List getFuziMenuTreeWithoutChildren() {
        QueryWrapper fuzi = new QueryWrapper<>();
        fuzi.select("menu_id", "menu_name", "parent_id","display_order"); // 指定查询的字段
        List menuList = fuziMapper.selectList(fuzi);
        return buildMenuTree(menuList); // 构建菜单树
    }

    // 构建父子级菜单树
    public List buildMenuTree(List menuList) {
        Map menuMap = new HashMap<>();

        // 将菜单放入Map中,以菜单ID作为键
        for (Fuzi menu : menuList) {
            menuMap.put(menu.getMenuId(), menu);
        }

        // 遍历菜单列表,将子菜单添加到对应的父菜单的children属性中
        List treeMenu = new ArrayList<>();
        for (Fuzi menu : menuList) {
            Long parentId = menu.getParentId();
            if (parentId == null || parentId == 0) {
                // 顶级菜单
                treeMenu.add(menu);
            } else {
                // 子菜单
                Fuzi parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    if (parentMenu.getChildren() == null) {
                        parentMenu.setChildren(new ArrayList<>());
                    }
                    parentMenu.getChildren().add(menu);
                }
            }
        }

        // 对顶级菜单及其子菜单按照 display_order 排序
        sortTreeMenu(treeMenu);

        return treeMenu;
    }

    // 递归排序树形结构的菜单
    private void sortTreeMenu(List treeMenu) {
        for (Fuzi menu : treeMenu) {
            if (menu.getChildren() != null && !menu.getChildren().isEmpty()) {
                // 递归排序子菜单
                sortTreeMenu(menu.getChildren());
            }
        }

        // 对当前层级的菜单按照 display_order 排序
        Collections.sort(treeMenu, Comparator.comparingLong(Fuzi::getDisplayOrder));
    }
    /*
    - Fuzi(menuId=1, menuName=顶级菜单1, parentId=0, displayOrder=1, children=[
  - Fuzi(menuId=3, menuName=子菜单1-1, parentId=1, displayOrder=1, children=null),
  - Fuzi(menuId=4, menuName=子菜单1-2, parentId=1, displayOrder=2, children=null)
  ])

- Fuzi(menuId=2, menuName=顶级菜单2, parentId=0, displayOrder=2, children=[
  - Fuzi(menuId=5, menuName=子菜单2-1, parentId=2, displayOrder=1, children=null)
  ])

     */
}

递归实现


    // 构建父子级菜单树
    public List buildMenuTree(List menuList) {
        Map menuMap = new HashMap<>();
        for (Fuzi menu : menuList) {
            menuMap.put(menu.getMenuId(), menu);
        }

        List treeMenu = new ArrayList<>();
        for (Fuzi menu : menuList) {
            if (menu.getParentId() == null || menu.getParentId() == 0) {
                buildChildMenu(menu, menuMap);
                treeMenu.add(menu);
            }
        }

        return treeMenu;
    }

    private void buildChildMenu(Fuzi parentMenu, Map menuMap) {
        Long parentId = parentMenu.getMenuId();
        List children = new ArrayList<>();

        menuMap.values().stream()
                .filter(menu -> parentId.equals(menu.getParentId()))
                .forEach(menu -> {
                    buildChildMenu(menu, menuMap);
                    children.add(menu);
                });

        children.sort(Comparator.comparingLong(Fuzi::getDisplayOrder));
        parentMenu.setChildren(children);
    }

未带有显示顺序的递归遍历

    public List getFuziMenuTreeWithoutChildren() {
        QueryWrapper fuzi = new QueryWrapper<>();
        fuzi.select("menu_id", "menu_name", "parent_id"); // 指定查询的字段
        List menuList = fuziMapper.selectList(fuzi);
        return buildMenuTree(menuList); // 构建菜单树
    }

    // 构建父子级菜单树
     public List buildMenuTree(List menuList) {
        Map menuMap = new HashMap<>();

        // 将菜单放入Map中,以菜单ID作为键
        for (Fuzi menu : menuList) {
            menuMap.put(menu.getMenuId(), menu);
        }

         System.out.println(menuMap);


        // 遍历菜单列表,将子菜单添加到对应的父菜单的children属性中
        List treeMenu = new ArrayList<>();
        for (Fuzi menu : menuList) {
            Long parentId = menu.getParentId();
            if (parentId == null || parentId == 0) {
                // 顶级菜单
                treeMenu.add(menu);
            } else {
                // 子菜单
                Fuzi parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    if (parentMenu.getChildren() == null) {
                        parentMenu.setChildren(new ArrayList<>());
                    }
                    parentMenu.getChildren().add(menu);
                }
            }
        }

        return treeMenu;
    }

你可能感兴趣的:(有关Java项目的参考文章,前端,数据库)