1.效果
最终生成的数据结构;可通过继承节点类(TreeVo),扩展属性;支持同级排序,默认升序排;
支持自定义根点id
{
id:'1',
name:'节点1',
parentId:'0',
sort:0,
children:[{
...
children:[{
...
}]
}]
}
2.使用demo
//1.节点类
public class TreeVo<T extends TreeVo> implements Comparable<TreeVo> {
protected String id;//节点id
protected String parentId;//父节点id
private String name;//名称
protected Integer sort;//同级排序
protected List<T> children = new ArrayList<>();//子节点集合
}
//2.自己的业务类
public class BusinessVo extends TreeVo<BusinessVo> {
//扩展属性...
}
//3.main方法使用示例
public static void main(String[] args) {
//定义根节点id
String rootId = "0";
//查找list结构列表
List<BusinessVo> vos= xxx.getList();
//创建树形工具实例
TreeUtil<BusinessVo> treeUtil = new TreeUtil<>();
//将普通列表转换成树型结构列表
TreeVo<BusinessVo> root = treeUtil.peerToLevel(vos, rootId );
}
3.工具类全代码
/**
* 节点类,可被继承,扩展不同类型的实体
*/
@NoArgsConstructor
@Data
public class TreeVo<T extends TreeVo> implements Comparable<TreeVo> {
protected String id;
protected String parentId;
private String name;
/**
* 排序 每一层单独排序
*/
protected Integer sort;
protected List<T> children = new ArrayList<>(
);
public TreeVo(String treeRootId) {
this.id = treeRootId;
}
public TreeVo(String id, String parentId, String name) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
@Override
public int compareTo(TreeVo o) {
return sort.compareTo(o.getSort());
}
}
/**
* 树形工具类
*/
public class TreeUtil<T extends TreeVo> {
/**
* 把列表组装为树形结构,结果返回一个空的根节点TreeVo,子节点类型根据T泛型适应,可通过继承TreeVo实体实现扩展类
* 空间换时间 将同级list转成树形对象
*
* @param list 需要组装的列表
* @param treeRootId 指定根id
* @return
*/
public synchronized TreeVo<T> peerToLevel(List<T> list, String treeRootId) {
//SysConstants.TREE_ROOT_ID 自定义根节点id
TreeVo<T> root = new TreeVo<T>(treeRootId);
List<T> parentList = list.stream().filter(l -> l.getParentId().equals(root.getId())).collect(Collectors.toList());
remove(list, parentList);
Collections.sort(parentList);
convert(parentList, list);
root.setChildren(parentList);
return root;
}
/**
* 把树形结构,解构为列表
* @param root 父节点
* @return 子节点列表
*/
public synchronized List<T> unLevelTree(TreeVo<T> root) {
List<T> childrenList = this.unConvert(root.getChildren());
return childrenList;
}
/**
* 获取所有子节点列表,无树结构
* @param nodeList
* @param parentId 父节点id
* @return
*/
public synchronized List<T> getAllChildList(List<T> nodeList, String parentId) {
TreeVo<T> treeVo = this.peerToLevel(nodeList, parentId);
return this.unLevelTree(treeVo);
}
private synchronized List<T> unConvert(List<T> childrenList) {
List<T> tempList = new ArrayList<>();
childrenList.forEach(item -> {
tempList.add(item);
if(item.getChildren()!=null && item.getChildren().size()>0) {
tempList.addAll(unConvert(item.getChildren()));
}
});
return tempList;
}
/**
* 转换递归
* @param parentList
* @param nodeList
*/
private synchronized void convert(List<T> parentList, List<T> nodeList) {
List<T> tempParentList = new ArrayList<>();
List<T> tempNodeList = new ArrayList<>();
parentList.forEach(parent -> {
nodeList.forEach(
node -> {
if (node.getParentId().equals(parent.getId())) {
parent.getChildren().add(node);
tempNodeList.add(node);
tempParentList.add(node);
}
}
);
Collections.sort(parent.getChildren());
});
//nodeList.removeAll(tempNodeList);
remove(nodeList, tempNodeList);
if (!nodeList.isEmpty() && !tempParentList.isEmpty()) {
convert(tempParentList, nodeList);
}
}
private void remove(List<T> sourceList, List<T> removeList) {
Iterator<T> iter = sourceList.iterator();
while(iter.hasNext()){
T s = iter.next();
for (T t : removeList) {
if(t.id.equals(s.id)) {
iter.remove();
}
}
}
}
}