Java获取无限层级的菜单并转换成树形结构

在很多应用程序中,我们经常会遇到需要获取无限层级菜单并将其转换成树形结构的问题。无限层级菜单是指菜单项之间存在父子关系,且层级关系可以无限延伸。在这篇文章中,我们将使用Java语言来解决这个问题,并通过代码示例来演示实现过程。

问题分析

无限层级菜单的数据结构可以用树来表示,每个菜单项可以看作是树的一个节点,父子关系表示为节点之间的连接关系。为了获取无限层级菜单并转换成树形结构,我们需要遍历菜单项的列表,根据节点之间的父子关系,构建出完整的树结构。

数据结构设计

在开始编写代码之前,我们先来设计一下数据结构。

菜单项(Menu)的属性包括菜单项的ID、名称、父ID和子菜单项的列表。其中,ID是唯一标识每个菜单项的属性,名称是菜单项显示的名称,父ID表示当前菜单项的父菜单项ID,子菜单项列表表示当前菜单项下的子菜单项。

class Menu {
    private String id;
    private String name;
    private String parentId;
    private List<Menu> children;
    
    // 省略getter和setter方法
}

获取无限层级菜单并转换成树形结构

下面是获取无限层级菜单并转换成树形结构的核心代码。我们使用递归的方式来实现。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class MenuUtils {
    public static List<Menu> convertToTree(List<Menu> menus) {
        Map<String, Menu> menuMap = new HashMap<>();
        List<Menu> rootMenus = new ArrayList<>();
        
        // 将菜单项放入map中,以便通过ID查找菜单项
        for (Menu menu : menus) {
            menuMap.put(menu.getId(), menu);
        }
        
        // 遍历菜单项列表,构建树结构
        for (Menu menu : menus) {
            String parentId = menu.getParentId();
            if (parentId == null || parentId.isEmpty()) {
                // 没有父ID的菜单项为根菜单项
                rootMenus.add(menu);
            } else {
                // 有父ID的菜单项加入到父菜单项的子菜单列表中
                Menu parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    parentMenu.getChildren().add(menu);
                }
            }
        }
        
        return rootMenus;
    }
}

代码示例

下面是一个示例,演示如何使用上述代码来获取无限层级菜单并转换成树形结构。

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 创建菜单项列表
        List<Menu> menus = new ArrayList<>();
        menus.add(new Menu("1", "菜单1", null, new ArrayList<>()));
        menus.add(new Menu("2", "菜单2", null, new ArrayList<>()));
        menus.add(new Menu("3", "菜单3", "1", new ArrayList<>()));
        menus.add(new Menu("4", "菜单4", "1", new ArrayList<>()));
        menus.add(new Menu("5", "菜单5", "3", new ArrayList<>()));
        
        // 转换成树形结构
        List<Menu> rootMenus = MenuUtils.convertToTree(menus);
        
        // 输出结果
        for (Menu menu : rootMenus) {
            printMenu(menu, 0);
        }
    }
    
    private static void printMenu(Menu menu, int level) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < level; i++) {
            sb.append("  ");
        }
        sb.append(menu.getName());
        System.out.println(sb.toString());
        
        for (Menu child : menu.getChildren()) {
            printMenu(child, level + 1);
        }
    }
}

运行上述代码,输出结果如下:

菜单1
  菜单3
    菜单5