码迷,mamicode.com
首页 > 其他好文 > 详细

正反建树工具类

时间:2021-04-01 13:43:38      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tree   spec   equals   java   add   als   invoke   parent   upper   

package com.tianee.webframe.util.tree;

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class TreeUtils {

    /**
     * 使用递归方法建树
     * 
     * @param list
     *            树的单个节点组成List,没有树结构(parent、children为null)
     * @param idAttr
     *            树节点id的属性名
     * @param parentIdAttr
     *            树节点的parentId的属性名
     * @return tree<T>
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws IntrospectionException
     */
    public static <T> List<T> buildTree(List<T> list, String idAttr, String parentIdAttr) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, IntrospectionException {
        List<T> trees = new ArrayList<>();
        for (T treeNode : list) {
            Method method = treeNode.getClass().getMethod("get" + firstUpperCase(parentIdAttr), null);
            Object value = method.invoke(treeNode, null);
            if (null == value) {
                trees.add(findChildren(treeNode, list, idAttr, parentIdAttr));
            }
        }
        return trees;
    }

    /**
     * 
     * @param t
     * @param treeNodes
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IntrospectionException
     */
    public static <T> T findChildren(T t, List<T> treeNodes, String idAttr, String parentIdAttr) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
            IntrospectionException {
        Method getIdMethod = t.getClass().getMethod("get" + firstUpperCase(idAttr));
        String id = String.valueOf(getIdMethod.invoke(t, null));
        for (T it : treeNodes) {
            Method getParentIdMethod = it.getClass().getMethod("get" + firstUpperCase(parentIdAttr));
            Object parentId = getParentIdMethod.invoke(it, null);
            if (id.equals(String.valueOf(parentId))) {
                Method getChildrenMethod = t.getClass().getMethod("getChildren");
                Object children = getChildrenMethod.invoke(t, null);
                if (null == children) {
                    Method setChildrenMethod = t.getClass().getMethod("setChildren", Set.class);
                    setChildrenMethod.invoke(t, new LinkedHashSet<T>());
                }
                ((HashSet<T>) getChildrenMethod.invoke(t, null)).add(findChildren(it, treeNodes, idAttr, parentIdAttr));
            }

        }
        return t;
    }

    /**
     * 
     * @param childrens
     *            叶子节点组成的List,没有树结构(parent、children为null)
     * @param list
     *            树所有的单个节点组成List,没有树结构(parent、children为null)
     * @param idAttr
     *            树节点id的属性名
     * @param parentIdAttr
     *            树节点的parentId的属性名
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws IntrospectionException
     */
    public static <T> List<T> reverseBuildTree(List<T> childrens, List<T> list, String idAttr, String parentIdAttr) throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException, IntrospectionException {
        Set<Object> path = new HashSet<>();
        for (T treeNode : childrens) {
            findParent(treeNode, list, idAttr, parentIdAttr, path);
        }

        List<T> newList = new ArrayList<>();
        for (T node : list) {
            Method method = node.getClass().getMethod("get" + firstUpperCase(idAttr), null);
            Object id = method.invoke(node, null);
            for (Object nodeId : path) {
                if (id.equals(nodeId)) {
                    newList.add(node);
                }
            }
        }

        List<T> trees = buildTree(newList, idAttr, parentIdAttr);
        return trees;
    }

    /**
     * 
     * @param <T>
     * @param t
     *            当前节点
     * @param treeNodes
     *            树所有的单个节点组成List,没有树结构(parent、children为null)
     * @param idAttr
     * @param parentIdAttr
     * @return
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
    public static <T> void findParent(T t, List<T> treeNodes, String idAttr, String parentIdAttr, Set<Object> path) throws IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchMethodException, SecurityException {
        Method getTIdMethod = t.getClass().getMethod("get" + firstUpperCase(idAttr), null);
        Object tId = getTIdMethod.invoke(t, null);
        path.add(tId);

        Method getParentIdMethod = t.getClass().getMethod("get" + firstUpperCase(parentIdAttr), null);
        Object parentId = getParentIdMethod.invoke(t, null);

        if (null == parentId) {
            return;
        }

        for (T node : treeNodes) {
            Method getIdMethod = node.getClass().getMethod("get" + firstUpperCase(idAttr));
            Object id = getIdMethod.invoke(node, null);
            if (parentId.equals(id)) {
                /*
                 * Method getParentMethod = t.getClass().getMethod("getParent",
                 * null); T parent = (T) getParentMethod.invoke(t, null);
                 * 
                 * if(null == parent){ }
                 * 
                 * Method setParentMethod = t.getClass().getMethod("setParent",
                 * t.getClass()); setParentMethod.invoke(t, node);
                 */

                findParent(node, treeNodes, idAttr, parentIdAttr, path);
            }
        }
    }

    /**
     * 字符串首字母大写
     * 
     * @param str
     * @return String 如果首位不是字母,返回空字符串
     */
    public static String firstUpperCase(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= ‘a‘ && ch[0] <= ‘z‘) {
            ch[0] = (char) (ch[0] - 32);
        } else if (ch[0] >= ‘A‘ && ch[0] <= ‘Z‘) {
        } else {
            return "";
        }
        return new String(ch);
    }
}

节点bean需要的属性,id(可以自定义,在调用方法时传入属性参数即可)、parentId(可以自定义,在调用方法时传入属性参数即可)、parent(节点对象)、children(节点对象的Set集合)

正反建树工具类

标签:tree   spec   equals   java   add   als   invoke   parent   upper   

原文地址:https://www.cnblogs.com/ezrealyi/p/14605048.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有
迷上了代码!