通过List/Map转树结构
文章目录
- 通过List/Map转树结构
- 前言
- 一、代码详情
- 1.创建接口实现公共方法
- 2.构建树工具类
- 3.调用示例
- 总结
前言
仅为了记录学习过程
一、代码详情
1.创建接口实现公共方法
代码如下:
/**
* 接口返回指定方法
* @param <K> 返回类型
*/
interface Node3<K,T>{
/**
* 获取node节点的Id
* @return
*/
K getNodeId();
/**
* 获取node节点的parentId
* @return
*/
K getNodePid();
/**
* 向children数组中添加对象
* @param node
* @return
*/
boolean addNodeChildren(T node);
/**
* 这个方法是用户自己判断2个对象的大小,用于排序自定义列时(不是int的列)
* 返回需要对比值的差值,如果为字符串则返回数字负数或者正数或者0
* @param o 这里是对比this和o中的值区别
* @param isAsc 排序方式true正序/false倒序
* @return
*/
int nodeEquels(T o,boolean isAsc);
}
2.构建树工具类
代码如下:
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
/**
* 构建树节点
* @author Mango
* 2023-12-14 00:45:30
* @param <T> 需要构建树的对象
* @param <K> 构建数ID的类型
*/
public class TreeUtils3<K,T extends Node3<K,T>> {
/**
* 定义排序支持类型
*/
private String[] typeNameArr = new String[] {"int","java.lang.Integer"};
/**
* 链式调用临时参数
*/
private List<T> tempList = new ArrayList<>();
/**
* 链式调用排序
* @param columnName
* @param isAsc
* @return
*/
public TreeUtils3<K,T> sort(String columnName,boolean isAsc) {
this.tempList = sort(this.tempList, columnName, isAsc);
return this;
}
/**
* 链式调用构件树
* @return
*/
public TreeUtils3<K,T> bulidTree(){
this.tempList = bulidTree(this.tempList);
return this;
}
/**
* 初始化list的值
* @return
*/
public TreeUtils3<K,T> init(List<T> t){
this.tempList = t;
return this;
}
/**
* 获取list的值
* @return
*/
public List<T> end(){
return this.tempList;
}
/**
* 排序
* @param sourceLsit 需要排序的List
* @param columnName 排序列
* @param isAsc 是否正序|true正,false反
* @return
*/
private List<T> sort(List<T> sourceList,String columnName,boolean isAsc) {
try {
//判断sourceLsit不能为空,为空直接返回空
if(sourceList==null || sourceList.size() == 0 || columnName==null ||columnName.equals("")) {
return new ArrayList<>();
}
//取出columnName字段类型
Class<?> classT = sourceList.get(0).getClass();//获取类属性
Field fieldColumn = classT.getDeclaredField(columnName);//获取列信息
fieldColumn.setAccessible(true);//设置可访问私有属性
String typeName = fieldColumn.getType().getName();
//判断如果
Collections.sort(sourceList, new Comparator<T>() {
@Override
public int compare(T o1, T o2) {
//判断typeName不是int/Integer属性就走自定义的排序规则
if(Arrays.asList(typeNameArr).contains(typeName)) {
//获取到o1和o2的column值
try {
if(isAsc)
return fieldColumn.getInt(o1) - fieldColumn.getInt(o2);
else
return fieldColumn.getInt(o2) - fieldColumn.getInt(o1);
} catch (Exception e) {
e.printStackTrace();
}
}else {//自己处理判断逻辑
return o1.nodeEquels(o2,isAsc);
}
return 0;
}
});
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
return sourceList;
}
/**
* 根据传入的List<T>构建树
* @param sourceLsit 树节点
* @return
*/
private List<T> bulidTree(List<T> sourceLsit){
//将bulidTree转为LinkedHashMap
LinkedHashMap<K,T> sourceLinkedMap = new LinkedHashMap<>();
for(T node:sourceLsit) {
sourceLinkedMap.put(node.getNodeId(),node);
}
return bulidTree(sourceLinkedMap);
}
/**
* 这里传入的参数一定为LinkedHashMap
* 根据传入的Map<K,T>构建树,K代表数据的ID,T代表对象
* @param sourceLsit 树节点
* @return
*/
private List<T> bulidTree(LinkedHashMap<K,T> sourceMap){
//使用向上查找的方式,先找到子节点放入父节点,然后记录子节点ID迭代删除,剩下的就是一棵树
List<K> removeList = new ArrayList<>();
for(T t : sourceMap.values()) {
T parentNode = sourceMap.get(t.getNodePid());
if(parentNode!=null) {
//将当前循环的节点丢入
parentNode.addNodeChildren(t);
removeList.add(t.getNodeId());
}
}
//删除
removeList.forEach(sourceMap::remove);
return new ArrayList<>(sourceMap.values());
}
}
3.调用示例
代码如下:
public static void main(String[] args) {
List<Node> nodeList = new ArrayList<>();
nodeList.add(new Node("120100","120000","天津市市辖区",0));
nodeList.add(new Node("110102","110100","西城区",1));
nodeList.add(new Node("110100","110000","北京市市辖区",0));
nodeList.add(new Node("120101","120100","和平区",0));
nodeList.add(new Node("110101","110100","东城区",0));
nodeList.add(new Node("110107","110100","石景山区",4));
nodeList.add(new Node("500105","500100","江北区",4));
nodeList.add(new Node("500000","000000","重庆市",0));
nodeList.add(new Node("510104","510100","锦江区",0));
nodeList.add(new Node("510114","510100","新都区",7));
nodeList.add(new Node("110105","110100","朝阳区",2));
nodeList.add(new Node("110106","110100","丰台区",3));
nodeList.add(new Node("130000","000000","河北省",3));
nodeList.add(new Node("120000","000000","天津市",0));
nodeList.add(new Node("500103","500100","渝中区",2));
nodeList.add(new Node("500104","500100","大渡口区",3));
nodeList.add(new Node("510000","000000","四川省",0));
nodeList.add(new Node("510100","510000","成都市区",0));
nodeList.add(new Node("120102","120101","河东区",1));
nodeList.add(new Node("120117","120100","宁河区",13));
nodeList.add(new Node("500100","500000","重庆市市辖区",0));
nodeList.add(new Node("110000","000000","北京市",0));
nodeList.add(new Node("500102","500100","涪陵区",1));
nodeList.add(new Node("000000","0","中国",0));
nodeList.add(new Node("500101","500100","万州区",0));
TreeUtils3<String, Node> treeUtils3 = new TreeUtils3<String, Node>();
System.out.println(JSON.toJSONString(treeUtils3.init(nodeList).sort("gid", false).bulidTree().end()));;
}
总结
该文章仅供自己学习,如果需要bug麻烦留言下谢谢。