将List转换为树形结构

在 Java 中,把List 转换为多级的树形结构非常常见。例如菜单数据是在数据库中“平铺”存储的,在做查询时,需要将其转换为树形结构,方便前端进行展示。

本文就以菜单作为案例,读者可以举一反三,实现自己的需求

数据库设计

将其命名为PERMISSIONS

字段名 类型 注释
CODE varchar 编码(主键)
PARENT_CODE varchar 父编码
NAME varchar 名称
TYPE tinyint 类型 0菜单 1按钮 2接口
URL varchar 前端路由或后端接口路由
CREATE_TIME datetime 创建时间
UPDATE_TIME datetime 更新时间

Java 处理

假设我们此时已经查询出一个列表ListPermissions类是与数据库对应的实体类,包含了PERMISSIONS表的所有字段,此刻就需要对其进行树形结构处理。

树形结构实体类

首先我们需要一个包含自身的树形结构实体类

/**
 * 权限树内容
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ApiModel(description = "权限树内容")
public class PermissionsTreeRes extends Permissions implements Serializable {
    private static final long serialVersionUID = 3107598961006613967L;

    /**
     * 权限树
     */
    @ApiModelProperty("权限树")
    private List<PermissionsTreeRes> children;
}

PermissionsTreeRes继承了Permissions,即拥有了数据库表中的所有字段。其自身又包含了类型为Listchildren属性,即子节点。

代码处理

public List<PermissionsTreeRes> buildPermissionsTree(List<Permissions> permissionsList) {
    return permissionsList.stream().filter(permissions -> ObjectUtils.isEmpty(permissions.getParentCod()))
            .map(permissions -> {
                PermissionsTreeRes treeRes = new PermissionsTreeRes();
                BeanUtils.copyProperties(permissions, treeRes);
                treeRes.setChildren(this.getPermissionsChildrenList(permissions.getCode(),permissionsList));
                return treeRes;
            }).collect(Collectors.toList());
}

private List<PermissionsTreeRes> getPermissionsChildrenList(String code, List<Permissions>permissionsList) {
    return permissionsList.stream().filter(permissions -> StringUtils.equals(permissions.getParentCode(),code))
            .map(permissions -> {
                PermissionsTreeRes treeRes = new PermissionsTreeRes();
                BeanUtils.copyProperties(permissions, treeRes);
                treeRes.setChildren(this.getPermissionsChildrenList(permissions.getCode(),permissionsList));
                return treeRes;
            }).collect(Collectors.toList());
}
  • buildPermissionsTree()方法内使用ObjectUtils.isEmpty(permissions.getParentCod())条件筛选出所有父编码为空的数据,即一级菜单数据。遍历中的setChildren()调用了getPermissionsChildrenList()方法,并传入自身的CODE,去寻找自己的子节点。

  • getPermissionsChildrenList()方法内使用递归不断的向下查找,直至filter后再无数据,便停止递归,进入下一次遍历。

你可能感兴趣的:(Java基础,java,开发语言)