package com.infish.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author wxl
* @Title: TreeUtil
* @Description: 通用Util,根据父节点关系将列表转树形结构
* @date 2018-12-10 17:54
*/
public class TreeUtil { /**
* @Description: 首字母转大写
* @param
* @return
* @throws
* @author wxl
* @date 2018-12-10 20:44
*/
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);
* @Description: List转Tree
* @param clazz 类.class
* @param dataList 数据列表
* @param idField ID字段名称
* @param parentIdField 父节点ID字段名称
* @param childrenField 孩子字段名称
* @param rootFlag 如果某个节点的ParentId等于rootFlag,即改节点为根节点
* @return
* @throws
* @author wxl
* @date 2018-12-10 20:44
*/
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(rootFlag.equals(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;
} /* public static void main(String[] args) throws Exception {
List<TreeNode> sourceList = new ArrayList<>();
TreeNode n1 = new TreeNode(); n1.setId(1);n1.setParentId(null); sourceList.add(n1);
TreeNode n2 = new TreeNode(); n2.setId(2);n2.setParentId(1); sourceList.add(n2);
TreeNode n3 = new TreeNode(); n3.setId(3);n3.setParentId(2); sourceList.add(n3);
List<TreeNode> treeNodes = toTree(TreeNode.class, sourceList, "id", "parentId", "children", null);
treeNodes.forEach(n-> System.out.println(n));
}*/
}

TreeUtil.java的更多相关文章

  1. 【原】无脑操作:EasyUI Tree实现左键只选择叶子节点、右键浮动菜单实现增删改

    Easyui中的Tree组件使用频率颇高,经常遇到的需求如下: 1.在树形结构上,只有叶子节点才能被选中,其他节点不能被选中: 2.在叶子节点上右键出现浮动菜单实现新增.删除.修改操作: 3.在非叶子 ...

  2. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  3. java 根据 根节点及所有子成员 构造树tree

    实体类entity package com.ompa.biz.entity; import java.util.ArrayList; import java.util.List; public cla ...

  4. java递归 处理权限管理菜单树或分类

    1.数据库表设计 2.实体类设计 package com.ieou.capsule.dto.SystemPermissions; import java.util.List; /** * 功能菜单类 ...

  5. Atitit。Tree文件解析器的原理流程与设计实现  java  c# php js

    Atitit.Tree文件解析器的原理流程与设计实现  java  c# php js 1. 解析原理与流程1 1.1. 判断目录  ,表示服  dirFlagChar = "└├─&quo ...

  6. Java生成菜单树(目录树)的几种方式

    本文介绍两种不同生成多级目录树的方式:1. 递归生成,2.  map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...

  7. 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题

    背景起因: 记起以前的另一次也是关于内存的调优分享下   有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...

  8. Elasticsearch之java的基本操作一

    摘要   接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...

  9. 论:开发者信仰之“天下IT是一家“(Java .NET篇)

    比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...

随机推荐

  1. leetcode 面试题 17.22. 单词转换(DFS+回溯)

    题目描述 思路分析 这题回溯,先想出它的空间解是什么,这里空间解,其实就是给的原字符串到结束字符串中间的变形过程,那么就可以容易的画出一个解空间树,用深度搜索进行搜索, 剪枝后,进入下一个维度,再进行 ...

  2. Message /index.jsp (line: [17], column: [45]) The JSP specification requires that an attribute name is preceded by whitespace

    Error: Message /index.jsp (line: [17], column: [45]) The JSP specification requires that an attribut ...

  3. 第二届 BJD wp(reverse和crypto)

    re 1.第一题拖入ida,flag就是直接明文摆着 2.第二题是8086的程序,拖入ida,发现有个jmp无限跳转,可能是段寄存器被修改了,ida无法将后面的汇编识别出来,所以后面才有很多无效数据, ...

  4. HCNA Routing&Switching之动态路由基本概念

    前文我们了解了静态路由的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14965433.html:今天我们来聊一聊动态路由相关概念: 首先我们要清楚什 ...

  5. pxe+kickstart部署多个版本的Linux操作系统(下)---实践篇

        我们在企业运维环境中,难免会遇到使用多个Linux操作系统的情况,如果每天都需要安装不同版本的Linux系统的话,那么使用Kickstart只能安装一种版本的Linux系统的方法则显得有些捉襟 ...

  6. 为LInux系统安装坚果云网盘

    首先 从www.jianguoyun.com/s/downloads/linux 中下载安装包(deb.rpm) deb 包安装及解决依赖方法 1. 使用 gdebi 安装,自动安装依赖 sudo g ...

  7. HCNA Routing&Switching之动态路由协议OSPF基础(二)

    前文我们主要了解了OSPF的区域.区域分类.路由器类型.OSPF的核心工作流程,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/15025533.html:今天 ...

  8. python使用笔记24--面向对象编程2

    类方法 类里面自带的方法,不用实例化就可以调用,想象,模型上自带的功能 类方法是公共的,在实例方法里面可以随意调用 但是在类方法里不能调用实例方法,不能使用实例变量,但是他可以调用其他的类方法 1 @ ...

  9. 微信小程序云开发-数据库-用户更新数据并提交

    一.wxml增加input输入框和[更新商品价格]按钮 在商品详情页新增[更新商品价格]按钮,wxml新增部分代码,input绑定事件,用于获取用户输入的内容.按钮绑定事件,用于更新商品价格.  二. ...

  10. PAT乙级:1082 射击比赛 (20分)

    PAT乙级:1082 射击比赛 (20分) 题干 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找 ...