通过泛型+反射+加自定义注解,任意实体集合递归形成树形结构
先上代码
第一个自定义注解TreeId (打在实体类的主键ID上)
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface TreeId {
String value() default "";
}
第二个自定义注解TreeParentId(打在实体类的父类ID上)
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface TreeParentId{
String value() default "";
}
第三个自定义注解TreeList(打在实体类的集合上)
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface TreeParentId{
String value() default "";
}
然后是最重要的工具类TreeUtil
import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.linkedList;
public class TreeUtil {
//递归形成树形结构
public static Collection buildTree(Collection collection, Long id) {
if (ObjectUtil.isNull(collection) || collection.size() == 0) {
return null;
}
Collection cs = new linkedList<>();
try {
for (Iterator it = collection.iterator(); it.hasNext(); ) {
T tree = it.next();
Class obj = tree.getClass();
Field[] fields = obj.getDeclaredFields();
Field parentIdField = getTreeFile(fields, TreeParentId.class);
if(ObjectUtil.isNotNull(parentIdField)){
if (parentIdField.get(tree).equals(id)) {
cs.add(tree);
it.remove();
}
}else{
throw new Exception("未找到父类Id");
}
}
if (ObjectUtil.isNull(cs) || cs.size() == 0) {
return null;
}
for (T tree : cs) {
Class obj = tree.getClass();
Field[] fields = obj.getDeclaredFields();
Field ListField = getTreeFile(fields, TreeList.class);
Field IdField = getTreeFile(fields, TreeId.class);
if(ObjectUtil.isNull(ListField)){
throw new Exception("未找到集合");
}
if(ObjectUtil.isNull(IdField)){
throw new Exception("未找到Id");
}
ListField.setAccessible(true);
ListField.set(tree,buildTree(collection,(Long) IdField.get(tree)));
}
}catch (Exception ex){
ex.printStackTrace();
}
return cs;
}
public static Field getTreeFile(Field[] fields, Class extends Annotation> t) {
for (Field field : fields) {
if(field.isAnnotationPresent(t)) {
field.setAccessible(true);
return field;
}
}
return null;
}
}
然后随便创建一个实体类并且在相对应的屬性上面打上对应的注解
@Data
public class user{
@TreeId()
private Long id;
private String name;
@TreeParentId()
private Long parentId;
@TreeList()
private List users;
}
最后是测试主方法
public static void main(String[] args) {
List users = new ArrayList<>();
for (int i=1;i<4;i++){
user user = new user();
user.setId(10l+i);
user.setParentId(0l);
users.add(user);
}
for (int i=1;i<4;i++){
user user = new user();
user.setId(20l+i);
user.setParentId(11l);
users.add(user);
}
for (int i=1;i<4;i++){
user user = new user();
user.setId(30l+i);
user.setParentId(21l);
users.add(user);
}
System.out.println(TreeUtil.buildTree(users,0l));
}
以下是结果:
[ user(id=11, name=null, parentId=0, users=[ user(id=21, name=null, parentId=11, users=[ user(id=31, name=null, parentId=21, users=null), user(id=32, name=null, parentId=21, users=null), user(id=33, name=null, parentId=21, users=null)]), user(id=22, name=null, parentId=11, users=null), user(id=23, name=null, parentId=11, users=null)]), user(id=12, name=null, parentId=0, users=null), user(id=13, name=null, parentId=0, users=null) ]



