Java基础(二十二) 递归

递归

      概述

  • 递归:指的是当前方法调用自己的现象。
  • 递归的分类:
        • 递归分为两类:直接递归和间接递归
        • 直接递归:成为方法自身调用自己的情况
        • 间接递归:可以归结为:方法A调用了方法B,方法B调用了方法C,方法C返回来又调用了方法A。

   注意事项:

      • 递归一定要有边界条件(条件限定),保证递归能够停止下来,否则会发生栈内存溢出。
      • 在递归当中虽然有限定条件,但是递归的次数也不能太多,否则也会发生栈内存异常现象。
      • 构造方法禁止递归。

使用递归实现累计求和

  计算1~n之间的和

  分析:1+2+3+...+n---->n + (n-1) + (n - 2) + ...+1的累加和,递归调用。

  代码示例:

1 public static void main(String[] args) {  
2         int sum = sum(10);
3         System.out.println(sum);
4     }
 /*
        定义一个方法,使用递归操作
        1 + 2 + 3+ 4 +...+n
        n+(n-1)+(n-2)+(n-3)+…+1
        已知:
            最大值:n
            最小值:1
            使用递归必须明确:
                    1.递归的结束条件
                    2.递归的目的:获取下一个被加的数字(n-1)
    */
    public static  int sum(int n){
        if(n == 1){
            return  1;
        }
        //获取下一个被加的数字
        return n + sum(n-1);
        //return  n == 1 ? 1 : sum(n-1) + n; 使用三目运算符更方便

    }

   备注:使用递归当中,main方法调用sum方法,sum方法会一直调用sum方法,导致在内存当中出现了很多个sum方法(频繁地创建方法、调用方法、销毁方法)效率非常低下,最好的方式就是for循环。

递归求阶乘

  阶乘:所有小于及等于该数的正整数的乘积。

  n的阶乘:n! = n * (n-1) * (n-2) * (n-3) * ... * 3 * 2 * 1

 

代码示例:

1 public  static  int producr(int n){
2 
3         if( n == 1){
4            return 1;  
5         }
6         return producr(n-1) * n;
7 }        

使用递归打印多级目录

   代码示例:

 1  public static void main(String[] args) {
 2         // 找到Hello文件的路径
 3         File file = new File("C:\\Users\\admin\\Desktop\\Hello");
 4         //调用getAllFiles()
 5         getAllFiles(file);
 6     }
 7 
 8     /*
 9         定义一个方法,参数传递File类型的目录
10         方法中要对目录进行遍历
11      */
12     public static void getAllFiles(File file) {
13         // 表明file此时是一个目录
14         System.out.println(file);
15         //首先先获取到它直接子目录和直接子文件
16         File[] files = file.listFiles();
17         // 遍历files目录
18        if (files != null) {
19             for (File f : files) {
20                 //判断如果得到的f是一个目录的,需要再次遍历
21                 if (f.isDirectory()) {
22                     //表明f是一个目录,则继续遍历这个目录
23                     //getAllFiles方法就是获取所有的文件,参数传递的刚好是目录,所以直接调用
24                     //getAllFiles目录
25                     System.out.println(f);
26                     getAllFiles(f);
27                 } else {
28                     System.out.println(f);
29                 }
30             } 
31         }
32     }

综合案例

  文件搜索

  搜索:C:\Users\admin\Desktop\Hello目录中的所有的.txt文件

  分析:

    1.目录搜索,无法判断有多少级目录,所以使用递归,遍历所有的目录

    2.遍历目录的时候,获取的是所有的子文件,通过文件的名称来进行诊断,判断是否符合给定的条件.txt

代码实现:

 1 public static void main(String[] args) {
 2         //构建一个File对象得到C:\Users\admin\Desktop\Hello路径
 3         File file = new File("C:\\Users\\admin\\Desktop\\Hello");
 4         getAllTxt(file);
 5 
 6     }
 7     /*
 8         定义一个方法,遍历所有的.txt文件
 9         方法中依然需要传递参数目录 
10      */ 
11     public static  void getAllTxt(File dir){
12         File[] files = dir.listFiles();
13         //遍历files
14         if(files != null){
15             for (File f : files) {
16                 //判断f是否是一个目录
17                 if(f.isDirectory()){
18                     getAllTxt(f);
19                 }else {
20                     //先获取文件的名称
21                     //再次判断名称是否以.txt结尾
22                     //链式编程
23                     if(f.getName().toLowerCase().endsWith(".txt")){
24                         System.out.println(f);
25                     }
26                 }
27             }
28         }
29     }

文件过滤器优化

    java.io.FileFilter是一个接口,是File的过滤器,该接口的对象可以传递给File类的ListFiles(FileFilter)作为参数,接口当中只有一个方法:

   boolean accept(File pathname):测试pathname是否应该包含在当前的File目录中,如果符合返回true

文件过滤器规则

文件过滤器规则

 

示例代码:

 1  public static void main(String[] args) {
 2         //构建一个File对象得到C:\Users\admin\Desktop\Hello路径
 3         File file = new File("C:\\Users\\admin\\Desktop\\Hello");
 4         getAllTxt(file);
 5     }
 6     /*
 7         定义一个方法,遍历所有的.txt文件
 8         方法中依然需要传参数目录
 9      */
10     public static void getAllTxt(File dir) {
11         //System.out.println(dir);
12         //File[] files = dir.listFiles();
13         File[] files = dir.listFiles(new FileFilterImpl());
14         //遍历files
15         for (File f : files) {
16             // 判断f是否是一个目录
17             if (f.isDirectory()) {
18                 getAllTxt(f);
19             } else {
20                 // 先获取文件的名称
21                 System.out.println(f);
22             }
23         }
24     }
25 // 实现类中的代码
26  @Override
27 public boolean accept(File pathname) {
28     if (pathname.isDirectory()) {
29         return true;
30     }
31     return pathname.getName()
32         .toLowerCase()
33         .endsWith(".txt");
34 }

Lambda优化

 

  示例代码:

1  //FilenameFilter接口
2 File[] files = dir.listFiles((d,name)  -> new File(d,name).isDirectory() || name.toLowerCase().endsWith(".txt"));
3 //FileFilter接口
4 File[] files = dir.listFiles(pathname ->pathname.getName().toLowerCase().endsWith(".txt") || pathname.isDirectory());

 

posted @ 2020-12-14 19:45  寒江雨  阅读(138)  评论(1编辑  收藏  举报