Java递归的原理以及各种案例演示

3,264 阅读6分钟

介绍Java中的递归以及代码演示,比如求递归阶乘、递归求和、递归求二进制数、递归遍历文件目录等。

1 递归概述

方法定义中调用方法本身的现象,称做递归。

使用注意

  1. 构造方法不能递归使用。
  2. 要定义结束条件,否则就是无限循环调用。
  3. 要避免内存溢出,递归深度太深容易造成内存溢出。

2 案例

2.1 求5的阶乘

递归解决问题的思想

在这里插入图片描述

递归解决问题的代码编写

在这里插入图片描述 递归代码

    public static void main(String[] args) {
        int factorial = factorial(5);
        System.out.println(factorial);
    }
​
    /**
     * num*((num-1)*((num-1-1)*((num-1-1-1)*…………)))
     * 5*((5-1)*((5-1-1)*((5-1-1-1)*(5-1-1-1-1))))
     *
     * @param num
     * @return
     */
    private static int factorial(int num) {
        //num大于1,则继续递归调用
        if (num > 1) {
            return num * factorial(num - 1);
        } else {
            //num小于等于1,则返回,结束递归
            return 1;
        }
    }
​

2.2 求1+2+3+...num的和

    public static void main(String[] args) {
        int sum = getSum(5);
        System.out.println(sum);
    }
​
​
    private static int getSum(int num) {
        //num大于1,则继续递归调用
        if (num > 1) {
            //返回和
            return num + getSum(num - 1);
        } else {
            //num小于等于1,则返回,结束递归
            return 1;
        }
    }

2.3 求一个正整数num的二进制

在这里插入图片描述

    public static void main(String[] args) {
        String binary = getBinary(9);
        System.out.println(binary);
    }
​
    private static String getBinary(int num) {
        //判断除以2商是否不为0,不为0就不是最后一次计算,继续递归
        if (num / 2 != 0) {
            return "" + getBinary(num / 2) + num % 2;
        } else {
            ///否则就是最后一次计算,返回
            return "" + num % 2;
        }
    }

2.4 打印第n项斐波那契数列的值

1、1、2、3、5、8、13、21、34、…… //后一项是前两项的和

    public static void main(String[] args) {
        long value = getValue(8);
        System.out.println(value);
    }
​
​
    private static long getValue(int n) {
        //如果n项为1或者2,则直接返回1
        if (n == 1 || n == 2) {
            return 1;
        }
        //否则递归调用,并把该项的前两项和相加,即为该项的值
        return getValue(n - 1) + getValue(n - 2);
    }

2.5 删除某个文件目录

window系统,删除目录的原理:

  1. 递归到目录的最底层。
  2. 先将目录当中存在的文件删除。
  3. 然后删除空目录。

总结:从里到外进行删除,要被删除的目录不能被占用。

注意:这样删除的文件回收站是找不到的,别吧重要文件删除了。

    public static void main(String[] args) {
        //输入要删除的文件目录地址
        delete("C:\Users\lx\Desktop\test");
​
    }
​
​
static void delete(String path) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
                return;
            }
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (file1.isFile()) {
                    file1.delete();
                } else {
                    delete(file1.getPath());
                }
            }
            file.delete();
        }
    }

2.5 文件清单

列举某个文件夹下面的所有文件到目录到另外一个txt文件中

    public static void main(String[] args) {
        //这里要遍历的目录随便找一个java工程的目录
        //输出到桌面text.txt中
        makeList("J:\Idea\JavaSE", "C:\Users\lx\Desktop\test.txt");
​
    }
​
    /**
     * 列举文件清单
     *
     * @param source 要遍历的目录
     * @param place  文件输出的路径
     */
    private static void makeList(String source, String place) {
        ArrayList<String> al = new ArrayList<>();
        File file = new File(source);
        File[] files = file.listFiles();
        assert files != null;
        for (File file1 : files) {
            if (file1.isFile()) {
                al.add(file1.getAbsolutePath());
            } else {
                //递归,遍历出所有java文件
                makeList(file1.getAbsolutePath(), place);
            }
        }
        if (al.isEmpty()) {
            return;
        }
        System.out.println();
        System.out.println("文件夹 :" + file.getAbsolutePath() + "   文件遍历开始===============>");
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(place, true))) {
            //续写
            for (String s : al) {
                bw.write(s);
                bw.newLine();
                bw.flush();
                System.out.println(s);
            }
            System.out.println("文件夹 :" + file.getAbsolutePath() + "文件遍历结束===============>");
            System.out.println();
​
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出结果演示:

文件夹 :J:\Idea\JavaSE.idea\inspectionProfiles   文件遍历开始===============>
J:\Idea\JavaSE.idea\inspectionProfiles\Project_Default.xml
文件夹 :J:\Idea\JavaSE.idea\inspectionProfiles文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE.idea   文件遍历开始===============>
J:\Idea\JavaSE.idea\compiler.xml
J:\Idea\JavaSE.idea\misc.xml
J:\Idea\JavaSE.idea\uiDesigner.xml
J:\Idea\JavaSE.idea\workspace.xml
文件夹 :J:\Idea\JavaSE.idea文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\annocation   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\annocation\ManAnnotation.java
J:\Idea\JavaSE\src\main\java\com\javase\annocation\Student.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\annocation文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\enums   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\enums\Direction.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\Direction2.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\Direction3.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\DirectionEnum1.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\DirectionEnum2.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\DirectionEnum3.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\DirectionTest.java
J:\Idea\JavaSE\src\main\java\com\javase\enums\EnumApi.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\enums文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\genericity   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\genericity\GenericDemo01.java
J:\Idea\JavaSE\src\main\java\com\javase\genericity\Genericity.java
J:\Idea\JavaSE\src\main\java\com\javase\genericity\ss.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\genericity文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\innerclass   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\innerclass\Outer1.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\innerclass文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\recursion   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\recursion\RecursionTest.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\recursion文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\reflect   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\reflect\ArrayListDemo.java
J:\Idea\JavaSE\src\main\java\com\javase\reflect\Student.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase\reflect文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase   文件遍历开始===============>
J:\Idea\JavaSE\src\main\java\com\javase\A.java
J:\Idea\JavaSE\src\main\java\com\javase\BaseTest.java
J:\Idea\JavaSE\src\main\java\com\javase\Operator.java
J:\Idea\JavaSE\src\main\java\com\javase\PerpetualCalendar.java
J:\Idea\JavaSE\src\main\java\com\javase\Teacher.java
文件夹 :J:\Idea\JavaSE\src\main\java\com\javase文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\annocation   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\annocation\ManAnnotation.class
J:\Idea\JavaSE\target\classes\com\javase\annocation\Student.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\annocation文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\enums   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction2.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction3$1.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction3$2.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction3$3.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction3$4.class
J:\Idea\JavaSE\target\classes\com\javase\enums\Direction3.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum1.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum2.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum3$1.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum3$2.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum3$3.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum3$4.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionEnum3.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionTest$1.class
J:\Idea\JavaSE\target\classes\com\javase\enums\DirectionTest.class
J:\Idea\JavaSE\target\classes\com\javase\enums\EnumApi.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\enums文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\genericity   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\genericity\GenericDemo01.class
J:\Idea\JavaSE\target\classes\com\javase\genericity\Genericity.class
J:\Idea\JavaSE\target\classes\com\javase\genericity\ss.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\genericity文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\innerclass   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\innerclass\Outer1$1Inner3.class
J:\Idea\JavaSE\target\classes\com\javase\innerclass\Outer1$Inner1.class
J:\Idea\JavaSE\target\classes\com\javase\innerclass\Outer1$Inner2.class
J:\Idea\JavaSE\target\classes\com\javase\innerclass\Outer1.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\innerclass文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\recursion   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\recursion\RecursionTest.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\recursion文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\reflect   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\reflect\ArrayListDemo.class
J:\Idea\JavaSE\target\classes\com\javase\reflect\Student.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase\reflect文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\com\javase   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\com\javase\A$B.class
J:\Idea\JavaSE\target\classes\com\javase\A.class
J:\Idea\JavaSE\target\classes\com\javase\BaseTest.class
J:\Idea\JavaSE\target\classes\com\javase\Operator.class
J:\Idea\JavaSE\target\classes\com\javase\PerpetualCalendar.class
J:\Idea\JavaSE\target\classes\com\javase\Teacher$Student.class
J:\Idea\JavaSE\target\classes\com\javase\Teacher.class
文件夹 :J:\Idea\JavaSE\target\classes\com\javase文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE\target\classes\META-INF   文件遍历开始===============>
J:\Idea\JavaSE\target\classes\META-INF\JavaSE.kotlin_module
文件夹 :J:\Idea\JavaSE\target\classes\META-INF文件遍历结束===============>
​
​
文件夹 :J:\Idea\JavaSE   文件遍历开始===============>
J:\Idea\JavaSE\pom.xml
文件夹 :J:\Idea\JavaSE文件遍历结束===============>

当然你也可以选择遍历某一个种类结尾的文件,比如.java,你只需要在过滤条件那里加上.java的条件就行了,这样就能实现更加精确的查找。

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!