方法内调用自己

分类:

  1. 直接递归:方法中直接调用自己
  2. 间接递归:通过第三个方法(里面调用自身语句)

注意事项:

  1. 递归一定要有条件,保证能够停下来,否则发生栈内存溢出
  2. 次数不能太多,否则发生栈内存溢出
  3. 构造方法,禁止递归(构造方法时创建对象使用的,一直递归会导致内存中有无数多个对象,编译报错)

调用前提:

  1. 调用方法时,方法主体不变,每次调用方法的参数不同

这样设条件时错误的,一九不停的在调用a方法
image.png
image.png

类似下面语句设置条件
image.png

明确两点:
1.递归的结束条件
2.递归的目的

案例

案例1:

image.png
之所以是return 1;,因为最后一次需要获得的数字是 1
!!!!
image.png
image.png

案例2:

image.png

    public static void main(String[] args) {
        File file = new File("E:\\A JI");
        getAllFile(file);
    }

    private static void getAllFile(File dir) {
        File[] files = dir.listFiles();

        for (File f1 : files) {
            //判断是否为文件夹
            if (f1.isDirectory()) {
                //如果是文件夹,继续遍历这个文件夹
                //利用getAllFile()方法:递归
                getAllFile(f1);
            } else {
                System.out.println(f1);
            }
        }
    }

案例3

搜索xxxx目录下中.java文件

    public static void main(String[] args) {
        File file = new File("E:\\A JI\\program\\java");
        getAllFile(file);
    }

    private static void getAllFile(File dir) {
        File[] files = dir.listFiles();

        for (File f1 : files) {
            //判断是否为文件夹
            if (f1.isDirectory()) {
                //如果是文件夹,继续遍历这个文件夹
                //利用getAllFile()方法:递归
                getAllFile(f1);

            } else {
                //实际就是比较字符串,因此将File对象转换为字符串对象
                //利用getName方法,或者getPath方法
//                String fileName = f1.getName();//路径不够全
//                String fileName = f1.getPath();//完整的路劲
                String fileName = f1.toString();//这个方法实际是调用getPath方法

                //将字符串全部转换为小写
                fileName = fileName.toLowerCase();

                //判断是否以.java结尾
                if (fileName.endsWith(".java")) {
                    System.out.println(f1);
                }

                //简化版本
                if (f1.toString().toLowerCase().endsWith(".java")) {
                    System.out.println(f1);
                }
            }
        }
    }

FileFilter过滤器:

File类中有两个ListFiles重载的方法,传递参数为过滤器

1.File[] listFiles(FileFilter filter)

作用:用来过滤文件(File对象)
抽象方法:用来过滤文件的方法
    boolean accept(File pathname) 测试**指定抽象路径名**是否在某个**路径名列表**中
参数:
    File pathname:使用ListFiles方法遍历目录,得到每一个文件对象

2.File[] listFiles(FilenameFilter filter)

作用:过滤文件
抽象方法:过滤文件的方法
    boolean accept(File dir, String name)
    参数:
        File dir:构造方法中被遍历的目录
        String name:用ListFiles方法遍历目录,获取每一个文件/文件夹的名称
     

注意:

两个过滤器无实现类,需要自己定义并且重写accept方法



    

java.io.FileFilter接口:

优化上述案例3

image.png

    public static void main(String[] args) {
        File file = new File("E:\\A JI\\program\\java");
        getAllFile(file);
    }

    private static void getAllFile(File dir) {
        File[] files = dir.listFiles(new FileFilterImpl());
        //listFiles方法:1.对构造方法中传递的目录进行遍历,获取目录中每一个文件/文件夹
        //2.调用参数传递的过滤器方法accept????(不是新建对象吗,重写的方法一定会执行?)
        //3.得到的File对象经过遍历,传递accept方法参数pathname

        for (File f1 : files) {
            //判断是否为文件夹
            if (f1.isDirectory()) {
                //如果是文件夹,继续遍历这个文件夹
                //利用getAllFile()方法:递归
                getAllFile(f1);

            } else {
                System.out.println(f1);
            }
        }
    }
    
public class FileFilterImpl implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        /**过滤规则
         *在accept方法中,判断File对象是否以.java结尾
         */
        //如果pathname是文件夹。返回true,继续遍历这个文件夹
        if (pathname.isDirectory()) {
            return true;
        }
        return pathname.getName().endsWith(".java");
    }
}

上述基础上再次优化案例3

1.使用匿名内部类
2.Lambda表达式
3.因为只有一行代码,继续简化Lambda表达式

    public static void main(String[] args) {
        File file = new File("E:\\A JI\\program\\java");
        getAllFile(file);
    }

    private static void getAllFile(File dir) {

        //匿名内部类写法
//        File[] files = dir.listFiles(new FileFilter() {
//
//            @Override
//            public boolean accept(File pathname) {
//                /**过滤规则
//                 *在accept方法中,判断File对象是否以.java结尾
//                 */
//                return pathname.getName().endsWith(".java") || pathname.isDirectory();
//            }
//        });

        //利用FilenameFilter过滤器
//        File[] files = dir.listFiles(new FilenameFilter() {
//            /**过滤规则
//             *在accept方法中,判断File对象是否以.java结尾
//             */
//            @Override
//            public boolean accept(File dir, String name) {
//                //前半,判断文件是否是.java结尾
//                //后半,通过封装为一个File对象
//                return name.toLowerCase().endsWith(".java") || new File(dir, name).isDirectory();
//            }
//        });

        //因为FileFilter与FilenameFilter只有一个accept语句
        //可以使用Lambda语句,优化匿名内部类
//        File[] files = dir.listFiles((File d, String name) -> {
//            return name.toLowerCase().endsWith(".java") || new File(d, name).isDirectory();
//        })

        //Lambda表达式继续简化
        File[] files = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".java") || new File(dir, name).isDirectory());

        for (File f1 : files) {
            //判断是否为文件夹
            if (f1.isDirectory()) {
                //如果是文件夹,继续遍历这个文件夹
                //利用getAllFile()方法:递归
                getAllFile(f1);

            } else {
                System.out.println(f1);
            }
        }
    }

waikiki
4 声望2 粉丝