import java.util.*;
public class TreeMenu {
public static void main(String[] args) {
// 构造测试数据
List<Menu> menuList = new ArrayList<>();
menuList.add(new Menu(1, "菜单1", 0));
menuList.add(new Menu(2, "菜单2", 0));
menuList.add(new Menu(3, "菜单1-1", 1));
menuList.add(new Menu(4, "菜单1-2", 1));
menuList.add(new Menu(5, "菜单2-1", 2));
menuList.add(new Menu(6, "菜单1-1-1", 3));
menuList.add(new Menu(7, "菜单1-1-2", 3));
menuList.add(new Menu(8, "菜单1-2-1", 4));
menuList.add(new Menu(9, "菜单2-1-1", 5));
// 转换为树形结构
List<Menu> treeMenuList = buildTree(menuList);
// 打印树形菜单
printTree(treeMenuList, "");
}
/**
* 将平铺结构的菜单列表转换为树形结构
* @param menuList 平铺结构的菜单列表
* @return 树形结构的菜单列表
*/
public static List<Menu> buildTree(List<Menu> menuList) {
List<Menu> treeMenuList = new ArrayList<>();
Map<Integer, Menu> menuMap = new HashMap<>();
// 首先将每个菜单放入map中,方便后续查找
for (Menu menu : menuList) {
menuMap.put(menu.getId(), menu);
}
// 遍历菜单列表,将每个菜单添加到其父菜单的子菜单列表中
for (Menu menu : menuList) {
Menu parentMenu = menuMap.get(menu.getParentId());
if (parentMenu == null) { // 如果是根菜单,则添加到树形结构的菜单列表中
treeMenuList.add(menu);
} else { // 如果不是根菜单,则添加到其父菜单的子菜单列表中
parentMenu.addChild(menu);
}
}
return treeMenuList;
}
/**
* 打印树形菜单
* @param treeMenuList 树形结构的菜单列表
* @param prefix 前缀,用于缩进
*/
public static void printTree(List<Menu> treeMenuList, String prefix) {
for (Menu menu : treeMenuList) {
System.out.println(prefix + menu.getName());
printTree(menu.getChildren(), prefix + " ");
}
}
}
class Menu {
private int id;
private String name;
private int parentId;
private List<Menu> children;
public Menu(int id, String name, int parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.children = new ArrayList<>();
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getParentId() {
return parentId;
}
public List<Menu> getChildren() {
return children;
}
public void addChild(Menu menu) {
children.add(menu);
}
}
使用说明:
1、构造一个Menu类,表示菜单,其中包含id、name、parentId和children四个属性。
2、使用buildTree方法将平铺结构的菜单列表转换为树形结构。
3、使用printTree方法打印树形菜单,其中prefix是前缀,用于控制缩进。
实现思路:
在buildTree方法中,我们使用了Map<Integer, Menu>类型的menuMap来存储每个菜单,其中key是菜单的id,value是菜单本身。这样,在遍历菜单列表时,我们可以通过menuMap.get(menu.getParentId())来查找每个菜单的父菜单,如果父菜单不为空,则将该菜单添加到父菜单的子菜单列表中。如果父菜单为空,则说明该菜单是根菜单,直接将其添加到树形结构的菜单列表treeMenuList中。
因此,treeMenuList是在buildTree方法中通过判断每个菜单是否为根菜单,并将根菜单添加到treeMenuList中得到的。最终,buildTree方法返回的就是一个树形结构的菜单列表,其中包含了所有的根菜单和它们的子菜单。