前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >递归查询文件树不要怕,看我用HashMap怎么玩!

递归查询文件树不要怕,看我用HashMap怎么玩!

作者头像
程序员牛肉
发布2024-09-26 13:22:19
900
发布2024-09-26 13:22:19
举报
文章被收录于专栏:小牛肉带你学Java

大家好,我是程序员牛肉。

最近在爆改我的网盘项目,其中有一个优化点困扰了我很多天:在网盘项目中会有很多需要查询文件树的地方。

比如说用户想要移动当前文件的时候,我们就需要把当前用户的文件夹树查询出来。

我最开始的写法可谓是一点脑子都不动了,直接递归就完事了!

本图片来自网络

在这里贴一下最开始的写法:

代码语言:javascript
复制
private void collectAllSubFolderFileIds(List<String> fileIds, String userId, String parentId, Integer deletionFlag) {
    fileIds.add(parentId);
    FileInfoQuery query = new FileInfoQuery();
    query.setUserId(userId);
    query.setFilePid(parentId);
    query.setDelFlag(deletionFlag);
    query.setFolderType(FileFolderTypeEnums.FOLDER.getType());
    List<FileInfo> fileInfos = this.fileInfoMapper.selectList(query);
    for (FileInfo fileInfo : fileInfos) {
        collectAllSubFolderFileIds(fileIds, userId, fileInfo.getFileId(), deletionFlag);
    }
}

可是这种写法的问题实在是太大了,每一次递归都要查询一次数据库,在查询高层次深度的文件数的时候,还可能会有溢出的风险。

一开始我总想着在递归上怎么优化。说实话,确实是有点难想。

可就在一个下午我在蹲厕所的时候,顿悟了。

我们还是不要用递归的手法分批查询文件来构建文件树了。直接一次性把一个文件下的所有文件都查出来,自己手动构建文件树。

基于这个思想其实设计起来就简单了很多。我先说代码逻辑,再谈代码实现。

首先我们从数据库中查到当前这个用户的所有文件夹。

查询出来之后,按照文件夹的父文件夹id进行分类,得到一个HashMap。键是父文件夹id。值是对应的文件夹。

最后我们开始遍历之前的所有文件夹。将当前文件夹的id当作key传入HashMap中,得到的对应值就是这个文件夹的子文件夹集合。

通过这种方式,我们就是实现了非递归查询当前用户的文件树。而为了代码简洁,我使用了大量的Stream流操作,因此看起来会比较绕。

代码语言:javascript
复制
    private List<FolderTreeNodeVO> sassembleFolderTreeNodeVOList(List<RPanUserFile> folderRecords) {
        if (CollectionUtils.isEmpty(folderRecords)) {
            return Lists.newArrayList();
        }
        List<FolderTreeNodeVO> mappedFolderTreeNodeVOList = folderRecords.stream().map(fileConverter::rPanUserFile2FolderTreeNodeVO).collect(Collectors.toList());
        Map<Long, List<FolderTreeNodeVO>> mappedFolderTreeNodeVOMap = mappedFolderTreeNodeVOList.stream().collect(Collectors.groupingBy(FolderTreeNodeVO::getParentId));
        for (FolderTreeNodeVO node : mappedFolderTreeNodeVOList) {

            List<FolderTreeNodeVO> children = mappedFolderTreeNodeVOMap.get(node.getId());

            if (CollectionUtils.isNotEmpty(children)) {
                node.getChildren().addAll(children);
            }
        }
        return mappedFolderTreeNodeVOList.stream().filter(node -> Objects.equals(node.getParentId(), FileConstants.TOP_PARENT_ID)).collect(Collectors.toList());
    }

但是这种方式也有自己的缺点:他只能够构建当前用户所有文件的文件树。并没有办法从局部开始查找。

所以在一些情况下我们还是要使用递归。比如在重命名一个文件夹的时候,要检查当前文件夹下的子目录有没有重名的情况。

所以我的思路还是有很大的不足的。不知道大家对于这种优化递归来讲,有什么解决方案呢?

关于“HashMap替代递归查询当前用户文件树”的介绍就到这里了。希望我的文章可以帮到你。

你们有什么更好的解决方法吗?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员牛肉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档