开发中会遇到很多需要层级展示的功能,这就需要一个树形结构数据来配合前端的渲染,网上查了很多,大都是递归方式实现的,下面是非递归方式的实现:
返回数据的结构:
@Data
@Accessors(chain = true)
public class CourseTypeTreeVo {
/**
* id
*/
private Long id;
/**
* 父id
*/
private Long parentId = 0L;
/**
* 层级
*/
private Integer level = 1;
/**
* 分类名
*/
private String name;
/**
* 子分类
*/
private List<CourseTypeTreeVo> childrenCourseType;
}
传入的数据结构:
@Data
@Accessors(chain = true)
public class CourseType implements Serializable {
private static final long serialVersionUID = 5596324500728175163L;
/**
* 分类id
*/
private Long id;
/**
* 分类父id,默认0表示没有父级
*/
private Long parentId = 0L;
/**
* 租户id
*/
private Long tenantId;
/**
* 层级
*/
private Integer level;
/**
* 分类名称
*/
private String name;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private Long createdBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createdTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private Long updatedBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updatedTime;
/**
* 删除标识 1=未删除 2 已删除
*/
private Integer delFlag;
}
一顿操作成树:
private List<CourseTypeTreeVo> toTree(List<CourseType> courseTypes) {
// 对象类型转换
List<CourseTypeTreeVo> list = new ArrayList<>();
for (CourseType item : courseTypes) {
CourseTypeTreeVo courseTypeTreeVo = new CourseTypeTreeVo();
// 用的hutool的
BeanUtil.copyProperties(item, courseTypeTreeVo);
list.add(courseTypeTreeVo);
}
// 根节点
List<CourseTypeTreeVo> result = list.stream().filter(item -> 1 == item.getLevel()).collect(Collectors.toList());
// id->实体
Map<Long, CourseTypeTreeVo> mapById = list.stream().collect(Collectors.toMap(CourseTypeTreeVo::getId, CourseTypeTreeVo -> CourseTypeTreeVo));
// children
list.removeAll(result);
// 按parentId分组
Map<Long, List<CourseTypeTreeVo>> mapByParentId = list.stream().collect(Collectors.groupingBy(CourseTypeTreeVo::getParentId));
// 关系绑定
for (Long key : mapByParentId.keySet()) {
mapById.get(key).setChildrenCourseType(mapByParentId.get(key));
}
return result;
}
基本思路是按父节点分组,把同属于一个父节点的集合赋值给父节点,绑定关系的时间复杂度最好是O(1),最坏是O(n-1),有没有更好的方式把这块再优化一下