Java 菜单列表转成树形结构

  在工作中菜单多的情况,会遇到list列表转为树形结构的菜单,特此记录下利用反射实现

一、实体类中格式

/**
 * 系统菜单表
 */
@ApiModel(value="系统菜单表")
@Data
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
  
    @TreeField(TreeField.Field.ID)
    @ApiModelProperty(value = "ID")
    private String id;

    @ApiModelProperty(value = "父ID")
    @TreeField(TreeField.Field.PARENDID)
    private String parentId;

   
    @ApiModelProperty(value = "菜单名称")
    private String menuName;

   
    @ApiModelProperty(value = "菜单路径")
    private String menuUrl;

   
    @ApiModelProperty(value = "图标")
    private String menuIcon;

  
    @ApiModelProperty(value = "子菜单")
    private List children;

  
}

二、自定义注解(通过反射)

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TreeField {
    TreeField.Field value();

    public static enum Field {
        ID,
        PARENTID,
        CHILDREN;

        private Field() {
        }
    }
}

三、工具类


import java.lang.reflect.Field;
import java.util.*;

public class TreeUtil {
   

    /**
     * list 转 tree
     *
     * @param list 节点集合
     */
    public static  List listToTree(List list) {
        List roots = new ArrayList<>();
        if (list == null || list.size() == 0) {
            return roots;
        }
        Class clazz = list.get(0).getClass();
        Field idField = getField(clazz, TreeField.Field.ID);
        Field pIdField = getField(clazz, TreeField.Field.PARENTID);
        Field childrenField = getField(clazz, TreeField.Field.CHILDREN);

        try {
            T parent;
            Map map = new HashMap<>(list.size());
            for (T node : list) {
                map.put(idField.get(node), node);
            }
            for (T node : list) {
                if ((parent = map.get(pIdField.get(node))) != null && !parent.equals(node)) {
                    if (childrenField.get(parent) == null) {
                        childrenField.set(parent, new ArrayList<>());
                    }
                    ((List) childrenField.get(parent)).add(node);
                } else {
                    roots.add(node);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return roots;
    }

    /**
     * tree 转 list
     *
     * @param tree 结构化集合
     */
    public static  List treeToList(List tree) {
        List list = new ArrayList<>();
        if (tree == null || tree.size() == 0) {
            return list;
        }
        Class clazz = tree.get(0).getClass();
        Field childrenField = getField(clazz, TreeField.Field.CHILDREN);
        // 使用Stack进行深度遍历(先进后出)
        try {
            Stack stack = new Stack<>();
            for (T root : tree) {
                stack.push(root);
                while (!stack.isEmpty()) {
                    T node = stack.pop();
                    if (childrenField.get(node) != null) {
                        List children = (List) childrenField.get(node);
                        // 子节点倒序入栈
                        Collections.reverse(children);
                        children.forEach(stack::push);
                        childrenField.set(node, null);
                    }
                    list.add(node);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    private static Field getField(Class clazz, TreeField.Field value) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //打开私有访问
            field.setAccessible(true);
            if (field.isAnnotationPresent(TreeField.class)) {
                TreeField anno = field.getAnnotation(TreeField.class);
                if (anno.value() == value) {
                    return field;
                }
            }
        }
        for (Field field : fields) {
            if (field.getName().equalsIgnoreCase(value.toString())) {
                return field;
            }
        }
        return null;
    }
}

你可能感兴趣的:(java,spring,maven)