package com.tree;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.formula.functions.T;
public class TreeUtils<T> {
/**
* 节点id
*/
private Integer id;
/**
* 节点名称 ,返回给前台的是一个装有TreeUtils的集合的数据,所以在前台显示数据的时候,el-tree的lable的名字的和这个一样
*/
private String name;
/**
* 节点类型,可通过维护Enum类动态获取对应表名 - 分表时可使用此字段
*/
// private String type;
/**
* 父节点id
*/
private Integer parentId;
/**
* 父节点中存放子节点的集合
*/
@SuppressWarnings("rawtypes")
private List<TreeUtils> childList;
/**
* 节点数据
*/
private T data;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// public String getType() {
// return type;
// }
// public void setType(String type) {
// this.type = type;
// }
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public List<TreeUtils> getChildList() {
return childList;
}
public void setChildList(List<TreeUtils> childList) {
this.childList = childList;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/**
* @Title: getTreeList
* @Description: TODO(从数据库中查询的数据)
* @param: @param listData
* @param: @param id
* @param: @param parentId
* @param: @param categoryName
* @param: @throws Exception
* @return: List<TreeUtils>
* @throws
*/
public static List<TreeUtils> getTreeList(List<?> listData ,String id,String parentId,String categoryName) throws Exception{
// 最终返回的结果
List<TreeUtils> resultList = new ArrayList<TreeUtils>();
Map<Integer ,Object> map = new HashMap<Integer,Object>();
for(int i =0;i<listData.size() && !listData.isEmpty();i++){
// 写一个与该方法差不多的方法,将得到TreeUtils的代码抽取出来
// 也可以将listData集合整个转换成装有TreeUtils的集合x,然后再循环x
TreeUtils treeUtils = new TreeUtils();
// id
// 返回值为Object无法直接转换成Integer,先toString,再转换成Integer。这里的返回值写成Object是因为多种类型字段的值都可以用该方法
treeUtils.setId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString()));
// 父id
treeUtils.setParentId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString()));
// 节点名
treeUtils.setName(TreeUtils.getFileValue(listData.get(i),categoryName).toString());
//System.out.println("节点名为+"+TreeUtils.getFileValue(listData.get(i),categoryName).toString());
// data:原对象中的所有属性,无children
treeUtils.setData(listData.get(i));
// 通过反射得到每条数据的id将数据封装的map集合中,id为键,元素本身为值
map.put(treeUtils.getId(),treeUtils);
// 将所有顶层元素添加到resultList集合中
//if( 0 == treeUtils.getParentId()){
// resultList.add(treeUtils);
// }
}
// 得到所有的顶层节点,游离节点也算作顶层节点
// 优点一,不用知道等级节点的id
// 优点而,只查询了一次数据库
for(int i =0;i<listData.size();i++){
if(!map.containsKey(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString()))){
resultList.add((TreeUtils) map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())));
}
}
for(int i =0;i<listData.size() && !listData.isEmpty();i++){
TreeUtils obj = (TreeUtils)map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i), parentId).toString()));
if(obj != null){
if(obj.getChildList() == null){
obj.setChildList(new ArrayList());
}
obj.getChildList().add(map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())));
}
}
return resultList;
}
/**
* @Title: getFileValue
* @Description: TODO(通过反射得到的数据类型的也是不一定的,所以这里我们返回值为Object)
* @notice: Object是无法直接转为Integer,现将Object转为String,然后再将String转为Integer
* @param: @param item
* @param: @param fileName
* @param: @throws Exception
* @return: Object
* @throws
*/
public static Object getFileValue(Object item,String fileName) throws Exception {
Class<?> aClass = item.getClass();
// 得到所有字段包括私有字段
Field file = aClass.getDeclaredField(fileName);
// 取消访问限制
file.setAccessible(true);
// 这里就体现出反射的意思了,我们通常都是通过对象拿到字段,这里是通过字段,将类的字节码对象为参数传入,来得到值
return file.get(item);
}
}