import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * 树注解工具类 * 父子关系构建树形数据结构 * @param <T> */ public class TreeAnnoUtil<T> { private Field[] fields; public TreeAnnoUtil(Class<T> clazz) { this.fields = clazz.getDeclaredFields(); } /** * 构建树 * @param orginals * @return */ public List<T> buildTree(List<T> orginals) { List<T> result = null; try { Map<String, T> dataMap = this.addToMap(orginals); result = this.doBuildTree(dataMap); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 原始数据添加到map集合 * @param orginals * @return */ private Map<String, T> addToMap(List<T> orginals) throws IllegalAccessException { // 创建Map,将原数据的 id 作为 key,原数据对象作为 value Map<String, T> dataMap = new LinkedHashMap<>(); for (T t : orginals) { for (Field field : fields){ Tree tree = field.getAnnotation(Tree.class); if(tree != null && tree.isId()){ field.setAccessible(true); dataMap.put(field.get(t)+"", t); break; } } } return dataMap; } /** * 执行构件树操作 * @param dataMap * @return * @throws Exception */ private List<T> doBuildTree(Map<String, T> dataMap) throws IllegalAccessException { List<T> result = new ArrayList<>(); for (Map.Entry<String, T> entry : dataMap.entrySet()) { T t = entry.getValue(); String parentId = null; for (Field field : fields){ Tree tree = field.getAnnotation(Tree.class); if(tree != null && tree.isParentId()){ field.setAccessible(true); Object parentIdObj = field.get(t); if(parentIdObj != null){ parentId = field.get(t)+""; } break; } } // 如果是根节点,直接添加到结果集合中 if (parentId == null || "0".equals(parentId)) { result.add(t); } else { // 如果不是根节点,找到父节点,然后添加到父节点的子节点中 T parentT = dataMap.get(parentId); for (Field field : fields){ Tree tree = field.getAnnotation(Tree.class); if(tree != null && tree.isChildren()){ field.setAccessible(true); List<T> children = (List<T>) field.get(parentT); children.add(t); break; } } } } return result; } // 行号,初始值为 0 private static ThreadLocal<Integer> rowNoThreadLocal = ThreadLocal.withInitial(() -> 0); /** * 打印 树名称,可模拟树结构 * 使用完 rowNoThreadLocal 记得关闭 * @param list * @param level */ private void printTree(List<OrgVo> list, int level){ String space = ""; for (int i = 0; i < level; i++) { space = " " + space; } //递归一次,层级+1; level++; for (int i = 0; i < list.size(); i++) { OrgVo orgVo = list.get(i); String label = orgVo.getLabel(); List<OrgVo> children = orgVo.getChildren(); int rowNo = rowNoThreadLocal.get() + 1;// 行号 rowNoThreadLocal.set(rowNo); System.out.println(space + label + "[层级" + (level) + "-行号" + rowNo + "]"); if(children.size() > 0){ printTree(children, level); } } } public static void main(String[] args) { long start = System.currentTimeMillis(); TreeAnnoUtil treeAnnoUtil = new TreeAnnoUtil(OrgVo.class); List<OrgVo> orginals = new ArrayList<>(); OrgVo rootOrgVo = new OrgVo(); rootOrgVo.setOrgId(-1); rootOrgVo.setLabel("name" + 0); rootOrgVo.setOrgPid(0); rootOrgVo.setOrderNo(0); orginals.add(rootOrgVo); for (int i = 1; i <= 5; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(-1); orgVo.setOrderNo(i); orginals.add(orgVo); } for (int i = 6; i <= 10; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(1); orgVo.setOrderNo(i); orginals.add(orgVo); } for (int i = 11; i <= 15; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(6); orgVo.setOrderNo(i); orginals.add(orgVo); } for (int i = 16; i <= 20; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(5); orgVo.setOrderNo(i); orginals.add(orgVo); } for (int i = 21; i <= 25; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(15); orgVo.setOrderNo(i); orginals.add(orgVo); } for (int i = 26; i <= 30; i++) { OrgVo orgVo = new OrgVo(); orgVo.setOrgId(i); orgVo.setLabel("name" + i); orgVo.setOrgPid(23); orgVo.setOrderNo(i); orginals.add(orgVo); } System.out.println("数据大小:"+orginals.size()); List<OrgVo> treeNodes = treeAnnoUtil.buildTree(orginals); System.out.println("耗时:"+(System.currentTimeMillis() - start)); treeAnnoUtil.printTree(treeNodes, 0); rowNoThreadLocal.remove(); // try { // ObjectMapper objectMapper = new ObjectMapper(); // String json = objectMapper.writeValueAsString(treeNodes); // System.out.println(json); // } catch (JsonProcessingException e) { // e.printStackTrace(); // } } }
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface Tree { // 是否是 id boolean isId() default false; // 是否是 parentId boolean isParentId() default false; // 是否是 children boolean isChildren() default false; }
import lombok.Data; import java.util.ArrayList; import java.util.List; @Data public class OrgVo { @Tree(isId = true) private int orgId; private String label; @Tree(isParentId = true) private int orgPid; private int orderNo; @Tree(isChildren = true) private List<OrgVo> children = new ArrayList<>(); }
标签:java,递归,Tree,List,private,field,构建,import,注解 From: https://www.cnblogs.com/sunhao1234/p/18435319