递归与文件过滤器

递归:

  • 递归:指在当前方法内调用自己的这种现象。

  • 递归的分类:

    • 递归分为两种,直接递归和间接递归。
    • 直接递归称为方法自身调用自己。
    • 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
  • 注意事项

    • 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
    • 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
    • 构造方法,禁止递归
public class Demo01DiGui {
    public static void main(String[] args) {
        // a();
        b(1);
    }

    /*
     * 3.构造方法,禁止递归
     * 编译报错:构造方法是创建对象使用的,不能让对象一直创建下去
     */
    public Demo01DiGui() {
        //Demo01DiGui();
    }

    /*
     * 2.在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
     * 4993
     *  Exception in thread "main" java.lang.StackOverflowError
     */
    private static void b(int i) {
        System.out.println(i);
        //添加一个递归结束的条件,i==5000的时候结束
        if(i==5000){
            return;//结束方法
        }
        b(++i);
    }

    /*
     * 1.递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 Exception in thread "main"
     * java.lang.StackOverflowError
     */
    private static void a() {
        System.out.println("a方法");
        a();
    }
}

递归练习:

使用递归计算1-n之间的和:

//使用递归计算1-n之间的和
package diGui;
import java.util.Scanner;
public class Demo01 {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        int n=sc.nextInt();
        System.out.println(leijia(n));
    }

    private static int leijia(int n) {
        if(n==1)
            return 1;
        return n+leijia(n-1);
    }
}

file

使用递归计算n的阶乘:

package diGui;
import java.util.Scanner;
public class Demo02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(jiecheng(n));
    }
    private static int jiecheng(int n) {
        if(n==1)
            return 1;
        return n*jiecheng(n-1);
    }
}

递归打印多级目录:

package diGui;
import java.io.File;
public class Demo03 {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles();
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}

file

file

综合案例:筛选打印

//筛选打印以png结尾的图片
//其实就是再刚才else里面加一个筛选语句
package diGui;
import java.io.File;
public class Demo03 {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles();
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}

file

file

FileFilter过滤器和FileNameFilter过滤器的原理及使用

/*
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器
    File[] listFiles(FileFilter filter)
    java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器。
        作用:用来过滤文件(File对象)
        抽象方法:用来过滤文件的方法
            boolean accept(File pathname) 测试指定抽象路径名是否应该包含在某个路径名列表中。
            参数:
                File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
    File[] listFiles(FilenameFilter filter)
    java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名。
        作用:用于过滤文件名称
        抽象方法:用来过滤文件的方法
            boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。
            参数:
                File dir:构造方法中传递的被遍历的目录
                String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称
    注意:
        两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则
 */

FileFilter过滤器:

//定义一个实现类,实现FileFilter过滤器
package diGui;
import java.io.File;
import java.io.FileFilter;
public class FileFilterImpl implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        if(pathname.isDirectory()){
            return true;
        }
        return pathname.getName().toLowerCase().endsWith(".png");
    }
}
//测试类,将实现类对象传给listFiles()方法就行
package diGui;
import java.io.File;
public class FileFilterDemo {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles(new FileFilterImpl());
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}

//可以直接使用匿名内部类,过滤规则,是文件夹或者是png文件
package diGui;
import java.io.File;
import java.io.FileFilter;
public class FileFilterDemo {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles(new FileFilter(){
            @Override
            public boolean accept(File pathname) {
                if(pathname.isDirectory()){
                    return true;
                }
                return pathname.getName().toLowerCase().endsWith(".png");
            }
        });
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}

//也可以使用Lambda表达式,过滤规则,是文件夹或者是png文件
package diGui;
import java.io.File;
import java.io.FileFilter;
public class FileFilterDemo {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles(f->{return f.getName().toLowerCase().endsWith(".png")||f.isDirectory();});
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}

FileNameFilter过滤器:

//同FileFilter过滤器,但它是传两个参数
//boolean accept(File dir, String name) dir表示当前路径,name则为文件名
package diGui;
import java.io.File;
import java.io.FilenameFilter;
public class FileFilterDemo {
    public static void main(String[] args) {
        File file=new File("E:\\美图");
        bianli(file);
    }
    private static void bianli(File file) {
        File [] files=file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                //dir路径和name要组合一下,才能判断是不是文件夹
                return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".png");
            }
        });
        for (File file1 : files) {
            if(file1.isDirectory()){
                System.out.println(file1);
                bianli(file1);
            }
            else
                System.out.println(file1);
        }
    }
}