递归查找树的子节点

@Data
@Builder
public class Menu {
    /**
     * id
     */
    public Integer id;
    /**
     * 名称
     */
    public String name;
    /**
     * 父id ,根节点为0
     */
    public Integer parentId;
    /**
     * 子节点信息
     */
    public List<Menu> childList;
}
 
 
 /**
     * 递归查询子节点
     * @param root  根节点
     * @param all   所有节点
     * @return 根节点信息
     */
    private List<Menu> getChildrens(Menu root, List<Menu> all) {
        List<Menu> children = all.stream().filter(m -> {
            return Objects.equals(m.getParentId(), root.getId());
        }).map(
                (m) -> {
                    m.setChildList(getChildrens(m, all));
                    return m;
                }
        ).collect(Collectors.toList());
        return children;
    }

我这里目标结构是这样:

就是root里面有个data和children,data是 主节点信息,children是子节点的信息,同时子节点还可以有子节点,主要信息也是data和children。

{
	"root": {
		"data": {
			"category": "Main",
			"fontSize": 30,
			"uid": "0",
			"expand": true,
			"richText": true,
			"isActive": false
		},
		"children": [{
			"data": {
				"uid": "92da6add-7d31-4442-b577-66dd0cb4a580",
				"expand": true,
				"richText": true,
				"isActive": false,
				"category": "Custom",
				"fontFamily": "Arial"
			},
			"children": [{
				"data": {
					"uid": "574f5ada-5566-4eb1-9f74-61dd68e82a5f",
					"expand": true,
					"richText": true,
					"isActive": false,
					"category": "Custom",
					"fontFamily": "Arial"
				},
				"children": []
			}]
		}]
	}
}

创建的实体类如下:

1.最外层的Root

@Data
public class DiagramRoot {
    private DiagramData data;
    private List<DiagramRoot> children;
}

2.data实体类

@Data
public class DiagramData {
    private Integer parent;
    private Integer uid;
    private String text;
    private String category;

    private List<DiagramData> children;
}

因为children里面又是data和children,所以肯定用到了递归。方法如下:

   private DiagramRoot getChildren(DiagramData rootVo, List<DiagramData> all) {
        DiagramRoot root = new DiagramRoot();
        try{
            root.setData(rootVo);
            List<DiagramData> childrenList = new ArrayList<>();
            for (DiagramData diagramData : all) {
                if(ObjectUtil.isNotNull(diagramData.getParent()) && rootVo.getUid().equals(diagramData.getParent())){
                    childrenList.add(diagramData);
                }
            }
            for (DiagramData childDiagramData : childrenList) {
                DiagramRoot childRoot = getChildren(childDiagramData, all);
                if(ObjectUtil.isNull(root.getChildren())){
                    List<DiagramRoot> children = new ArrayList<>();
                    children.add(childRoot);
                    root.setChildren(children);
                }else{
                    root.getChildren().add(childRoot);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return root;
    }

调用方法如下:

@RequestMapping(value = "/getDiagramV3FileContent/{appFileInfoId}", method = RequestMethod.GET)
    public ResponseVo getDiagramV3FileContent(HttpServletRequest request, @PathVariable Long appFileInfoId) {
        try {
            OfficeFileVo officeFileVo = new OfficeFileVo();
            AppFileInfo appFileInfo = baseService.getById(appFileInfoId);
            if (ObjectUtil.isEmpty(appFileInfo)) {
                return AppResultBuilder.faile(ResultCodeEnum.FILE_ID_ERROR);
            }
            BeanUtils.copyProperties(appFileInfo, officeFileVo);

            DiagramRoot root = new DiagramRoot();

            //组装数据
            if (Objects.equals(officeFileVo.getOfficeFlag(), Constants.INTEGER_DEFAULT_ONE)) {
                if (ObjectUtil.equal(Constants.INTEGER_DEFAULT_ZERO, appFileInfoId)) {
                    return AppResultBuilder.success(null, ResultCodeEnum.SUCCESS);
                }

                //1.数据是从mongo拿出来的
                SpaceOfficeContentVo spaceOfficeContentVo = mongoService.getInfo(appFileInfoId, OfficeMongoEnum.CONTENT_COLLECTION.getCode());
                if (ObjectUtil.isNotEmpty(spaceOfficeContentVo)) {
                    officeFileVo.setContent(spaceOfficeContentVo.getContent());
                    ArrayList arrayList = (ArrayList)((LinkedHashMap) spaceOfficeContentVo.getContent()).get("data");
                    String s = JSON.toJSONString(arrayList);
                    //2.转换成类DiagramData的数据了
                    List<DiagramData> all = JSONArray.parseArray(s, DiagramData.class);

                    //获取到主节点
                    DiagramData diagramData  = all.stream().filter(x -> ObjectUtil.isNull(x.getParent())).findFirst().orElse(null);
                    root = getChildren(diagramData, all);
                }
            }
            return AppResultBuilder.success(root, ResultCodeEnum.SUCCESS);
        } catch (Exception e) {
            return AppResultBuilder.faile(ResultCodeEnum.SERVER_ERROR);
        }
    }

运行结果如下:

{
    "code": 200,
    "data": {
        "children": [
            {
                "children": [
                    {
                        "children": [],
                        "data": {
                            "category": "Person",
                            "children": [],
                            "key": -4,
                            "parent": -2,
                            "text": "分支主题1的子节点"
                        }
                    }
                ],
                "data": {
                    "category": "Custom",
                    "children": [],
                    "key": -2,
                    "parent": 0,
                    "text": "分支主题1"
                }
            },
            {
                "children": [
                    {
                        "children": [],
                        "data": {
                            "category": "Person",
                            "children": [],
                            "key": -10,
                            "parent": -3,
                            "text": "分支主题2的子节点"
                        }
                    },
                    {
                        "children": [],
                        "data": {
                            "category": "Person",
                            "children": [],
                            "key": -12,
                            "parent": -3,
                            "text": "分支主题2的子节点"
                        }
                    }
                ],
                "data": {
                    "category": "Custom",
                    "children": [],
                    "key": -3,
                    "parent": 0,
                    "text": "分支主题2"
                }
            },
            {
                "children": [
                    {
                        "children": [],
                        "data": {
                            "category": "Person",
                            "children": [],
                            "key": -9,
                            "parent": -5,
                            "text": "分支主题3的子节点"
                        }
                    }
                ],
                "data": {
                    "category": "Custom",
                    "children": [],
                    "key": -5,
                    "parent": 0,
                    "text": "分支主题3"
                }
            },
            {
                "children": [
                    {
                        "children": [],
                        "data": {
                            "category": "Custom",
                            "children": [],
                            "key": -7,
                            "parent": -6,
                            "text": "分支主题4的子节点111"
                        }
                    },
                    {
                        "children": [
                            {
                                "children": [],
                                "data": {
                                    "category": "Person",
                                    "children": [],
                                    "key": -11,
                                    "parent": -8,
                                    "text": "分支主题4的子节点222的子节点1111"
                                }
                            }
                        ],
                        "data": {
                            "category": "Custom",
                            "children": [],
                            "key": -8,
                            "parent": -6,
                            "text": "分支主题4的子节点222"
                        }
                    }
                ],
                "data": {
                    "category": "Custom",
                    "children": [],
                    "key": -6,
                    "parent": 0,
                    "text": "分支主题4"
                }
            }
        ],
        "data": {
            "category": "Main",
            "children": [],
            "key": 0,
            "parent": 0,
            "text": "2023年的第一场雪"
        }
    },
    "msg": "成功"
}

但是后来又说要文件的其他信息:

就又包装了一层:

这里的content主要是为了存放刚刚的节点信息,现在要做的就是把root整体放进去。

public class OfficeFileVo extends AppFileInfo {

    @ApiModelProperty(value = "内容(大JSON)")
    private Object content;
}
AppFileInfo是前端需要的文件信息:
public class AppFileInfo extends BaseEntity {

    @ApiModelProperty(value="APPID,自增,唯一",example = "1" ,dataType = "Long")
    @TableId(type = IdType.ASSIGN_ID)
    private Long appFileInfoId;
    @ApiModelProperty(value="用户ID",example = "1" ,dataType = "Long")
    private Long hhxsUserId;
    @ApiModelProperty(value="上传者ID",example = "1" ,dataType = "Long")
    private Long uploadUserId;    
    @ApiModelProperty(value="文件名称",example = "a.mp4/b.png/c.pdf")
    private String fileName;
    @ApiModelProperty(value="文件地址",example = "1")
    private String fileUrl;
    @ApiModelProperty(value="缩略图URL",example = "1")
    private String fileAvatar;
    @ApiModelProperty(value="预览URL(视频文件转MP4地址)")
    private String filePreview;
    @ApiModelProperty(value="是否公开(0公开,1非公开)",example = "1" ,dataType = "Integer")
    private Integer fileIsPublic;
    .....
   }

代码更改如下:

@RequestMapping(value = "/getDiagramV3FileContent111/{appFileInfoId}", method = RequestMethod.GET)
    public ResponseVo getDiagramV3FileContent111(HttpServletRequest request, @PathVariable Long appFileInfoId) {
        try {
            OfficeFileVo officeFileVo = new OfficeFileVo();
            AppFileInfo appFileInfo = baseService.getById(appFileInfoId);
            if (ObjectUtil.isEmpty(appFileInfo)) {
                return AppResultBuilder.faile(ResultCodeEnum.FILE_ID_ERROR);
            }
            BeanUtils.copyProperties(appFileInfo, officeFileVo);

            //组装数据
            if (Objects.equals(officeFileVo.getOfficeFlag(), Constants.INTEGER_DEFAULT_ONE)) {
                if (ObjectUtil.equal(Constants.INTEGER_DEFAULT_ZERO, appFileInfoId)) {
                    return AppResultBuilder.success(null, ResultCodeEnum.SUCCESS);
                }

                //1.数据是从mongo拿出来的
                SpaceOfficeContentVo spaceOfficeContentVo = mongoService.getInfo(appFileInfoId, OfficeMongoEnum.CONTENT_COLLECTION.getCode());
                if (ObjectUtil.isNotEmpty(spaceOfficeContentVo)) {
                    ArrayList arrayList = (ArrayList)((LinkedHashMap) spaceOfficeContentVo.getContent()).get("data");
                    String s = JSON.toJSONString(arrayList);
                    //2.转换成类DiagramData的数据了
                    List<DiagramData> all = JSONArray.parseArray(s, DiagramData.class);

                    DiagramData diagramData  = all.stream().filter(x -> ObjectUtil.isNull(x.getParent())).findFirst().orElse(null);
                    DiagramRoot root = getChildren(diagramData, all);
                    //之前组装的data和children放到这里,又包一层
                    officeFileVo.setContent(root);
                }
            }
            return AppResultBuilder.success(officeFileVo, ResultCodeEnum.SUCCESS);
        } catch (Exception e) {
            return AppResultBuilder.faile(ResultCodeEnum.SERVER_ERROR);
        }

最后运行结果如下:

{
    "code": 200,
    "data": {
        "appFileInfoId": 7129910661768640,
        "appInfoId": 4225135329640576,
        "content": {
            "children": [],
            "data": {
                "category": "Main",
                "children": [],
                "parent": 0,
                "text": "中心主题",
                "uid": 0
            }
        },
        "deleteTime": 1731568041,
        "ext1": "",
        "ext2": "",
        "ext3": "{\"officeLayout\":\"logicalStructure\",\"memberList\":[],\"officeAllLineColor\":\"#fe5858\",\"officeLineW\":3,\"officeRainbowLine\":true}",
        "ext4": "",
        "fileAvatar": "",
        "fileIsPublic": 0,
        "fileIsTop": 0,
        "fileLabel": "",
        "fileMd5": "",
        "fileName": "中心主题.egte",
        "filePreview": "",
        "fileSort": 1731566889957,
        "fileSource": 0,
        "fileType": 51,
        "fileUrl": "http://10.1.62.111/diagramv3/#/preview?appFileInfoId=7129910661768640&fileType=51&operate=&goback=1",
        "graphicFormat": "0",
        "hhxsUserId": 3076134814912832,
        "imageSource": 0,
        "insertedTime": "2024-11-14 14:48:10",
        "logicDelete": 0,
        "officeFlag": 1,
        "params": {},
        "privateFlag": 0,
        "recoveryShow": 1,
        "relyOn": -1,
        "sharedFlag": "0",
        "shortcut": "0",
        "updateTime": "2024-11-14 15:03:22",
        "uploadFlag": 2,
        "uploadUserId": 3076134814912832,
        "version": 1
    },
    "msg": "成功"
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值