Java实现递归删除菜单和删除目录及目录下所有文件

目录

一、什么是递归?

二、示例分析


一、什么是递归?

递归调用是一种特殊的嵌套调用,是某个函数调用自己或者是调用其他函数后再次调用自己的,只要函数之间互相调用能产生循环的则一定是递归调用,递归调用一种解决方案,一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了,递归是一种思想,只不过在程序中,就是依靠函数嵌套这个特性来实现了。

递归调用就是在当前的函数中调用当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。

二、示例分析

案例1:递归删除菜单及其所有子菜单

  • 菜单实体类
java 复制代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * 系统菜单
 */
@Data
@TableName(value = "menu")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    /*** 菜单ID*/
    @TableId(type = IdType.INPUT)
    private Long menuId;

    /*** 父级菜单ID*/
    private Long upMenuId;

    /*** 菜单编码*/
    private String menuCode;

    /*** 菜单名称*/
    private String menuName;

    /*** 菜单级别(默认1级)*/
    private Integer menuLevel;

    /*** 菜单页面打开方式(1-本页面打开 2 新标签页打开 3-新窗口打开)*/
    private Integer pageOpenType;

    /*** 菜单类型(1-菜单 2-权限按钮)*/
    private Integer menuType;

    /*** 菜单图标*/
    private String menuIcon;

    /*** 菜单URL*/
    private String menuUrl;

    /*** 菜单序号*/
    private Integer menuOrder;

    /*** 菜单描述*/
    private String menuDesc;

    /*** 数据状态(0-删除 1-正常) */
    private Integer dataFlag;

    /*** 是否禁用(0-否 1-是)*/
    private Integer isDisable;

    /*** 创建人ID*/
    private Long createId;

    /*** 创建时间*/
    private Date createTime;

}
  • 实现代码
java 复制代码
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.test.java.domain.entity.Menu;
import com.test.java.mapper.MenuMapper;
import com.test.java.service.MenuService;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Override
    public Integer deleteMenuById(Long menuId) {
        // 校验当前要删除的菜单是否存在
        Menu menu = menuMapper.selectById(menuId);
        if (null == menu) {
            throw new RuntimeException("菜单已删除");
        }

        // 创建list集合,用于封装所有要删除的菜单ID
        List<Long> menuIdList = new ArrayList<>();
        // 向menuIdList集合设置删除菜单id(根据id删除菜单)
        this.queryMenuChildById(menuId, menuIdList);
        // 把当前菜单id封装到idList里面
        menuIdList.add(menuId);

        // 批量删除当前菜单 及其所有子菜单
        return menuMapper.deleteBatchIds(menuIdList);
    }


    // 根据当前菜单id,查询其所有子菜单id,再封装到idList集合
    private void queryMenuChildById(Long menuId, List<Long> idList) {
        // 查询菜单里面子菜单id
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("up_menu_id", menuId);
        List<Menu> childMenuList = menuMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(childMenuList)) {
            // 把childMenuList里面菜单id值获取出来,封装idList里面,做递归查询
            childMenuList.forEach(item -> {
                //封装idList里面
                idList.add(item.getMenuId());
                //递归查询
                this.queryMenuChildById(item.getMenuId(), idList);
            });
        }
    }

}

案例2:递归删除目录及其目录中所有文件

  • 实现代码
java 复制代码
import lombok.extern.slf4j.Slf4j;

import java.io.File;

/**
 * 文件相关工具类
 */
@Slf4j
public class FileUtils {

    /**
     * 删除文件或文件夹
     *
     * @param path 文件路径
     * @return 返回true(删除成功), 返回false(删除失败)
     */
    public static boolean deleteFileOrDirectory(String path) {
        File file = new File(path);
        // 判断文件是否存在
        if (file.exists()) {
            // 判断是否为文件
            if (file.isFile()) {
                // 删除文件
                return deleteFile(path);
            } else {
                // 删除文件夹
                return deleteDirectory(path);
            }
        } else {
            return false;
        }
    }

    /**
     * 删除文件
     *
     * @param path 文件路径
     * @return 返回true(删除成功), 返回false(删除失败)
     */
    public static boolean deleteFile(String path) {

        boolean result = false;

        File file = new File(path);
        if (file.isFile() && file.exists()) {
            result = file.delete();
            log.info("删除文件成功:{}", path);
            return result;
        } else {
            log.info("删除文件失败:{}", path);
            return result;
        }
    }

    /**
     * 删除文件夹(先删文件再删目录)
     *
     * @param path 文件夹路径
     * @return 返回true(删除成功), 返回false(删除失败/文件夹不存在)
     */
    public static boolean deleteDirectory(String path) {
        if (!path.endsWith(File.separator)) {
            // 补齐文件分隔符
            path = path + File.separator;
        }
        File directoryFile = new File(path);
        // 文件不存在、不是一个目录就打印退出返回false
        if (!directoryFile.exists() || !directoryFile.isDirectory()) {
            log.info("文件夹不存在,{}", path);
            return false;
        }

        boolean flag = true;
        // 获取所有的子文件及子文件夹
        File[] files = directoryFile.listFiles();
        if (files != null) {
            // 循环删除
            for (File file : files) {
                // 删除子文件
                if (file.isFile()) {
                    flag = deleteFile(file.getAbsolutePath());
                    if (!flag) {
                        break;
                    }
                } else {// 删除子文件夹
                    flag = deleteDirectory(file.getAbsolutePath());
                    if (!flag) {
                        break;
                    }
                }
            }
        }
        if (!flag) {
            log.info("删除文件夹失败");
            return false;
        }
        // 最后删除当前文件夹
        if (directoryFile.delete()) {
            log.info("删除文件夹成功,{}", path);
            return true;
        } else {
            log.info("删除文件夹失败,{}", path);
            return false;
        }
    }

}

以上代码直接粘贴复制即可直接使用。

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

相关推荐
励志成为嵌入式工程师29 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉1 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer1 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq1 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~2 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616882 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
wheeldown2 小时前
【数据结构】选择排序
数据结构·算法·排序算法
aloha_7892 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java3 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet