public static List listToTreeList(List treeList) {
if(CollectionUtils.isEmpty(treeList)){
return treeList;
}
Map> treeLevelMap = new HashMap<>();
Map> treeParentCodeMap = new HashMap<>();
treeList.stream().forEach(x -> {
//按照树等级分组
listGroupByGetFun(treeLevelMap,x,x.getLevel());
//按照父编码分组
listGroupByGetFun(treeParentCodeMap,x,x.getParentCode());
});
List rootTree = new ArrayList<>();
//获取树的最大层级
Integer maxLevel = treeLevelMap.entrySet().stream().map(x ->
x.getKey()).max(Integer::compareTo).get();
int i = 1;
//循环level
while (i <= maxLevel) {
List currentTreeList = treeLevelMap.get(i);
currentTreeList.stream().forEach(x -> {
//设置子集合相当于 x.setChild(list);
//把当前节点的子集合从treeParentCodeMap中取出通过setChild方法赋值。
ArrayList childList = (ArrayList)
treeParentCodeMap.get(x.getCode());
x.setChild(childList);
});
if (i == 1) {
rootTree.addAll(currentTreeList);
}
i++;
}
return rootTree;
}
private static void listGroupByGetFun(Map> map,TreeObj obj,K key) {
//分组方法(存储分组map,被分组对象)
//分组属性
if (key == null) {
return;
}
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(obj);
}
普通版本
private static final int LEVEL_INDEX =0;
private static final int CODE_INDEX =1;
private static final int PARENT_CODE_INDEX =2;
private static final int CHILD_LIST_INDEX =3;
private static Method[] methods;
public static List listToTreeList(List treeList) {
if(CollectionUtils.isEmpty(treeList)){
return treeList;
}
Class cls = (Class) treeList.get(0).getClass();
TreeAnnotations annotation = cls.getAnnotation(TreeAnnotations.class);
if(null == annotation){
return treeList;
}
TreeUtils.methods = getMethod(cls);
Map> treeLevelMap = new HashMap<>();
Map> treeParentCodeMap = new HashMap<>();
treeList.stream().forEach(x -> {
//按照树等级分组
listGroupByGetFun(treeLevelMap, x, getLevel(x));
//按照父编码分组
listGroupByGetFun(treeParentCodeMap,x, getParentCode(x));
});
List rootTree = new ArrayList<>();
//获取最大层级数
Integer maxLevel = treeLevelMap.entrySet().stream().map(x -> x.getKey()).max(Integer::compareTo).get();
int i = 1;
//循环level
while (i <= maxLevel) {
List currentTreeList = treeLevelMap.get(i);
currentTreeList.stream().forEach(x -> {
//设置子集合相当于 x.setChild(list);
//把当前节点的子集合从treeParentCodeMap中取出通过setChild方法赋值。
List childList = treeParentCodeMap.get(getCode(x));
setChild(x,childList);
});
if (i == 1) {
rootTree.addAll(currentTreeList);
}
i++;
}
return rootTree;
}
//这里为了可读性特意提取出来,后期可自行去留
private static Integer getLevel(T x){
return (Integer) getMethod(methods,x,LEVEL_INDEX);
}
private static String getParentCode(T x){
return (String)getMethod(methods,x,PARENT_CODE_INDEX);
}
private static String getCode(T x){
return (String)getMethod(methods,x,CODE_INDEX);
}
private static void setChild(T x,List childList){
setMethod(methods,x,CHILD_LIST_INDEX,childList);
}
private static void listGroupByGetFun(Map> map,T obj,K key) {
//分组方法(存储分组map,被分组对象)
//分组属性
if (key == null) {
return;
}
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(obj);
}
private static void setMethod(Method[] methods,T t,int index,Object setValue){
try {
methods[index].invoke(t,setValue);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
private static Object getMethod(Method[] methods,T t,int index){
try {
return methods[index].invoke(t);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
private static Method[] getMethod(Class cls){
Method[] methods = new Method[4];
for(Field field:cls.getDeclaredFields()) {
try {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(),cls);
if(field.isAnnotationPresent(LevelAnnotation.class)){
methods[LEVEL_INDEX] = pd.getReadMethod();
}
if(field.isAnnotationPresent(CodeAnnotation.class)){
methods[CODE_INDEX]= pd.getReadMethod();
}
if(field.isAnnotationPresent(ParentCodeAnnotation.class)){
methods[PARENT_CODE_INDEX]= pd.getReadMethod();
}
if(field.isAnnotationPresent(ChildListAnnotation.class)){
methods[CHILD_LIST_INDEX] = pd.getWriteMethod();
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
return methods;
}
泛型通用版本,这个可读性差点,可以先看普通版本再看这个泛型版本。
@Data
@TreeAnnotations()
public class TreeObj {
private String name;
@LevelAnnotation
private Integer level;
@CodeAnnotation
private String code;
@ParentCodeAnnotation
private String parentCode;
@ChildListAnnotation
private ArrayList child;
@Override
public String toString() {
return "TreeTest{" +
"name='" + name + '\'' +
", level=" + level +
", code='" + code + '\'' +
", parentCode='" + parentCode + '\'' +
'}';
}
}
测试树对象
注解类就是名字不一样,其他都一样。注解的作用是标识出哪些字段是层级、哪些字段是code。
可以自己根据实际情况变更。