树结构工具-TreeUtil(注解的方式实现)
将有树结构的集合封装为树结构
使用步骤:
1. 添加依赖
<dependency>
<groupId>com.github.appundefined</groupId>
<artifactId>treeUtil</artifactId>
<version>2.1-RELEASE</version>
</dependency>
2. 在需要转换为树结构的对象字段上添加核心注解3个
@TreeElement(name = "id")
private String id; //新增支持类型int、Long、Integer
@TreeElement(name = "pid")
private String pid; //新增支持类型int、Long、Integer
@TreeElement(name = "children")
@Transient//如果是jpa实体则需添加该注解
private List<Object> children = new ArrayList<>();//(注:没有List集合需要添加一个)
3. 调用
List trees = TreeUtils.ListToTree(objects);
4. 源码地址
https://github.com/AppUndefined/javaUtils.git
5. 源码
一个注解:TreeElement
package com.github.appundefined.tree;
import java.lang.annotation.*;
@Target(value= {ElementType.FIELD})
@Documented
@Retention(value = RetentionPolicy.RUNTIME)
public @interface TreeElement {
String name();
}
一个注解:TreeTreeUtils
package com.github.appundefined.tree;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class TreeUtils {
/**
* 根节点值/Root node value
*/
static String rootNode = "0";
/**
* String class路径
*/
static String stringType = "class java.lang.String";
/**
* Long class路径
*/
static String longType = "class java.lang.Long";
/**
* Integer class路径
*/
static String integerType = "class java.lang.Integer";
/**
* int
*/
static String intType = "int";
/**
* 主键编号/Primary key id
*/
static String id = "id";
/**
* 父节点ID/Parent node id
*/
static String pid = "pid";
/**
* 子节点集合/Child node collection
*/
static String children = "children";
/**
* 将列表转换为列表树/Convert List to List Tree
* @param trees t
* @param <T> t
* @return result
* @throws IllegalAccessException result
*/
public static <T> List<T> ListToTree(List<T> trees) throws IllegalAccessException {
//Root node collection
List<T> rootList = new ArrayList<T>();
HashMap<Object, List<T>> pidAndTrees= new HashMap<>();
for (final T t : trees) {
Object value = getValue(t, pid);
if(value!=null){
if(pidAndTrees.get(value)!=null) {
pidAndTrees.get(value).add(t);
}else{
pidAndTrees.put(value,new ArrayList<T>(){{this.add(t);}});
}
Object type = getType(t, pid);
if (stringType.equals(type)) {
if (rootNode.equals(value)) {
rootList.add(t);
}
} else if (longType.equals(type)) {
if (((Long)Long.parseLong(rootNode)).equals(value)) {
rootList.add(t);
}
}else if (integerType.equals(type)) {
if (((Integer)Integer.parseInt(rootNode)).equals(value)) {
rootList.add(t);
}
}
else if (intType.equals(type)) {
if (((Integer)Integer.parseInt(rootNode)).equals(value)) {
rootList.add(t);
}
}
}
}
buildChilTree(rootList,pidAndTrees);
return rootList;
}
/**
* 获取与对象的指定注释值对应的字段值
* Get the field value corresponding to the specified annotation value of the object
* @param t
* @param key
* @param <T>
* @return
* @throws IllegalAccessException
*/
private static <T> Object getValue(T t,String key) throws IllegalAccessException {
Field[] fields = t.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
TreeElement treeElement = field.getAnnotation(TreeElement.class);
if(treeElement!=null){
String name = treeElement.name();
if(key.equals(name)){
Object o = field.get(t);
return o;
}
}
}
return null;
}
/**
* 设置与对象的指定注释值对应的字段值
* Get the field value corresponding to the specified annotation value of the object
* @param t
* @param key
* @param <T>
* @return
* @throws IllegalAccessException
*/
private static <T> Object setValue(T t,String key) throws IllegalAccessException {
Field[] fields = t.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
TreeElement treeElement = field.getAnnotation(TreeElement.class);
if(treeElement!=null){
String name = treeElement.name();
if(key.equals(name)){
field.set(t,null);
}
}
}
return null;
}
/**
* 获取对象的指定字段对应的字段类型
* Get the field type corresponding to the specified field of the object
* @param t
* @param key
* @param <T>
* @return
* @throws IllegalAccessException
*/
public static <T> Object getType(T t,String key) throws IllegalAccessException {
Field[] fields = t.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
TreeElement treeElement = field.getAnnotation(TreeElement.class);
if(treeElement!=null){
String name = treeElement.name();
if(key.equals(name)){
return field.getType().toString();
}
}
}
return null;
}
/**
* 递归构造/Recursive construction
* @param currentTrees
* @param trees
* @param <T>
* @throws IllegalAccessException
*/
private static <T> void buildChilTree(List<T> currentTrees, HashMap<Object, List<T>> trees) throws IllegalAccessException {
for (T t : currentTrees) {
Object currentId = getValue(t, id);
//Data exists with current id as pid
if(trees.get(currentId)!=null){
List list = (List) getValue(t, children);
list.addAll(trees.get(currentId));
buildChilTree(trees.get(currentId),trees);
}else {
setValue(t, children);
}
}
}
}
版权声明:本文为u014542583原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。