import org.springframework.beans.BeanUtils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName TreeUtil
* @Description 树状图列表转换
* @Author LD
* @DATE 2021/4/15 18:16
* @Version 1.0
*/
public class TreeUtil {
/**
* @Description: 首字母转大写
*/
public static String firstCharToUpperCase (String str) {
if (str == null) {
return null;
}
if ("".equals(str)) {
return "";
}
char[] cs = str.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
/**
* 调用示例:示例: List<TreeNode> head = toTree(TreeNode.class,nodeList,"id","parentId","children",0L);
*
* @param clazz 类.class
* @param dataList 数据列表
* @param idField ID字段名称
* @param parentIdField 父节点ID字段名称
* @param childrenField 孩子字段名称
* @param rootFlag 如果某个节点的ParentId等于rootFlag,即改节点为根节点
* @Description: List转Tree
*/
public static <T> List<T> toTree (Class<T> clazz, List<T> dataList, String idField, String parentIdField, String childrenField, Object rootFlag) throws Exception {
List<T> treeList = new ArrayList<>();
Map<Object, T> map = new HashMap<>();
Map<Object, Boolean> flag = new HashMap<>();
String getIdStr = "get" + firstCharToUpperCase(idField);
String getParentIdStr = "get" + firstCharToUpperCase(parentIdField);
String getChildrenStr = "get" + firstCharToUpperCase(childrenField);
String setChildrenStr = "set" + firstCharToUpperCase(childrenField);
Method getIdMethod = null;
Method getParentIdMethod = null;
Method getChildrenMethod = null;
Method setChildrenMethod = null;
try {
getIdMethod = clazz.getDeclaredMethod(getIdStr);
getParentIdMethod = clazz.getDeclaredMethod(getParentIdStr);
getChildrenMethod = clazz.getDeclaredMethod(getChildrenStr);
setChildrenMethod = clazz.getDeclaredMethod(setChildrenStr, List.class);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("转树形结构-通过反射获取方法错误!", e);
}
for (T node : dataList) {
map.put(getIdMethod.invoke(node), node);
Object parentIdTmp = getParentIdMethod.invoke(node);
if (rootFlag == null || "".equals(rootFlag)) {
if (parentIdTmp == null || "".equals(parentIdTmp)) {
treeList.add(node);
}
} else {
if (String.valueOf(rootFlag).equals(String.valueOf(parentIdTmp))) {
treeList.add(node);
}
}
}
for (T node : dataList) {
T parentNode = map.get(getParentIdMethod.invoke(node));
if (parentNode != null) {
List<T> invoke = (List<T>) getChildrenMethod.invoke(parentNode);
if (invoke == null) {
invoke = new ArrayList<>();
setChildrenMethod.invoke(parentNode, invoke);
}
invoke.add(node);
}
}
return treeList;
}
/**
* 调用示例:示例: List<TreeNode> head = toTree(TreeNode.class,nodeList,"id","parentId","children","name",0L,"name");
*
* @param clazz 类.class
* @param dataList 数据列表
* @param idField ID字段名称
* @param parentIdField 父节点ID字段名称
* @param childrenField 孩子字段名称
* @param searchField 模糊查询的字段
* @param text 模糊查询值
* @param <T>
* @return
* @throws Exception
* @Description: List转Tree
*/
public static <T> List<T> toTree (Class<T> clazz, List<T> dataList, String idField, String parentIdField, String childrenField, String searchField, Object rootFlag, String text) throws Exception {
List<T> treeList = new ArrayList<>();
Map<Object, T> map = new HashMap<>();
Map<Object, Boolean> flag = new HashMap<>();
String getIdStr = "get" + firstCharToUpperCase(idField);
String getParentIdStr = "get" + firstCharToUpperCase(parentIdField);
String getChildrenStr = "get" + firstCharToUpperCase(childrenField);
String setChildrenStr = "set" + firstCharToUpperCase(childrenField);
String getSearchStr = "get" + firstCharToUpperCase(searchField);
Method getIdMethod = null;
Method getParentIdMethod = null;
Method getChildrenMethod = null;
Method getSearchMethod = null;
Method setChildrenMethod = null;
try {
getIdMethod = clazz.getDeclaredMethod(getIdStr);
getParentIdMethod = clazz.getDeclaredMethod(getParentIdStr);
getChildrenMethod = clazz.getDeclaredMethod(getChildrenStr);
setChildrenMethod = clazz.getDeclaredMethod(setChildrenStr, List.class);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("转树形结构-通过反射获取方法错误!", e);
}
for (T node : dataList) {
map.put(getIdMethod.invoke(node), node);
Object parentIdTmp = getParentIdMethod.invoke(node);
if (rootFlag == null || "".equals(rootFlag)) {
if (parentIdTmp == null || "".equals(parentIdTmp)) {
treeList.add(node);
}
} else {
if (String.valueOf(rootFlag).equals(String.valueOf(parentIdTmp))) {
treeList.add(node);
}
}
}
for (T node : dataList) {
T parentNode = map.get(getParentIdMethod.invoke(node));
if (parentNode != null) {
List<T> invoke = (List<T>) getChildrenMethod.invoke(parentNode);
if (invoke == null) {
invoke = new ArrayList<>();
setChildrenMethod.invoke(parentNode, invoke);
}
invoke.add(node);
}
}
return search(clazz, childrenField, searchField, treeList, text);
}
/**
* 模糊搜索
*
* @param clazz
* @param childrenField
* @param searchField
* @param data
* @param text
* @param <T>
* @return
* @throws Exception
*/
public static <T> List<T> search (Class<T> clazz, String childrenField, String searchField, List<T> data, String text) throws Exception {
if (StringUtil.isBlank(text)) {
return data;
}
Map<Object, T> map = new HashMap<>();
Map<Object, Boolean> flag = new HashMap<>();
String getChildrenStr = "get" + firstCharToUpperCase(childrenField);
String setChildrenStr = "set" + firstCharToUpperCase(childrenField);
String getSearchStr = "get" + firstCharToUpperCase(searchField);
Method getChildrenMethod = null;
Method getSearchMethod = null;
Method setChildrenMethod = null;
try {
getChildrenMethod = clazz.getDeclaredMethod(getChildrenStr);
getSearchMethod = clazz.getDeclaredMethod(getSearchStr);
setChildrenMethod = clazz.getDeclaredMethod(setChildrenStr, List.class);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("转树形结构-通过反射获取方法错误!", e);
}
List<T> res = new ArrayList<>();
for (T treeNode : data) {
List<T> children = (List<T>) getChildrenMethod.invoke(treeNode);
if (children != null && children.size() > 0) {
List<T> searchData = search(clazz, childrenField, searchField, children, text);
T tn = clazz.newInstance();
BeanUtils.copyProperties(treeNode, tn);
setChildrenMethod.invoke(tn, searchData);
if (getSearchMethod.invoke(treeNode).toString().contains(text) || searchData.size() > 0) {
res.add(tn);
}
} else {
if (getSearchMethod.invoke(treeNode).toString().contains(text)) {
res.add(treeNode);
}
}
}
return res;
}
}
java list 转换树形结构 支持模糊搜索
最新推荐文章于 2024-04-25 11:06:39 发布