正反建树工具类

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);
	}
}

  

posted @ 2021-04-01 10:11  EzrealYi  阅读(53)  评论(0编辑  收藏  举报