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<>();
}