文章目录
Java【递归及过滤器】
一、递归
1、概念&分类&注意事项2、练习:递归计算1-n的和3、练习:递归计算阶乘4、练习:递归打印多级目录5、综合案例:文件搜索 二、过滤器接口
1、`java.io.FileFilter`2、`java.io.FilenameFilter`
一、递归 1、概念&分类&注意事项概念:方法自己调用自己
分类:
| 直接递归 | 自己调用自己 |
|---|---|
| 间接递归 | A调用B,B调用C,C调用A |
注意事项:
递归必须有终止条件。否则会导致Exception in thread "main" java.lang.StackOverflowError栈溢出。次数不能太多。否则也会导致栈溢出。构造方法禁止递归。会发生编译报错:构造方法创建对象使用的,一直递归会导致内存中有无数多个对象。
递归的使用前提:方法的主体不变,每次调用方法的参数不同。
2、练习:递归计算1-n的和
public class Demo02Recursion {
public static void main(String[] args) {
int s = sum(10);
System.out.println("s=" + s);
}
private static int sum(int n) {
// 结束条件
if(n == 1) return 1;
// 递归调用
return n + sum(n-1);
}
}
3、练习:递归计算阶乘
public class Demo03Recursion {
public static void main(String[] args) {
long jc = jc(10);
System.out.println(jc(6));
}
private static long jc(int n) {
if(n ==1 ) return 1;
return n*jc(n-1);
}
}
4、练习:递归打印多级目录
public class Demo04Recursion {
public static void main(String[] args) {
File file = new File("/Users/yanzhuang/Desktop/a/C");
printAllFile(file);
}
public static void printAllFile(File dir){
System.out.println(dir);// 打印初始目录
File[] files = dir.listFiles();
// 遍历目录中的所有File对象
for (File file : files) {
// 如果file是目录的话,递归调用
if(file.isDirectory()) {
printAllFile(file);
} else {
// 如果不是,直接打印
System.out.println(file);
}
}
}
}
5、综合案例:文件搜索
要求:搜索指定目录中的".java"文件
主要方法:public File[] listFiles() : 返回一个抽象路径名数组,表示由此抽象路径名表示的目录中的文件。
public class Demo05Recursion {
public static void main(String[] args) {
File file = new File("/Users/yanzhuang/IdeaProjects/basic-code/day19-advanced/src/com/s0cket/day19");
printAllFiles(file);
}
public static void printAllFiles(File dir){
// 获取dir中的所有File对象
File[] files = dir.listFiles();
// 遍历File对象数组
for (File file : files) {
// 判断file对象是否是文件夹
if(file.isDirectory()) {
// 是文件夹继续递归调用printAllFiles方法
printAllFiles(file);
} else {
// 不是文件夹
// 就是文件
// 判断是否是.java结尾
if(file.getName().toLowerCase().endsWith(".java")){
// 如果是java文件,打印file.toString
System.out.println(file);
}
}
}
}
}
二、过滤器接口
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器。
public File[] listFiles(FileFilter filter) public File[] listFiles(FilenameFilter filter)1、java.io.FileFilter
作用:用来过滤文件(File对象)
抽象方法:用来过滤文件的方法boolean accept(File pathname) 测试指定抽象路径名是否应该包含在某个路径名列表中。参数:
File pathname–使用listFiles方法遍历目录,得到的每一个文件对象。
传统实现方式(实现类重写accept方法)
public class FileFilterImpl implements FileFilter {
@Override
public boolean accept(File pathname) {
// 如果pathname是一个文件夹,则返回true,继续遍历这个文件夹
if(pathname.isDirectory()){
return true;
}
// 不是文件夹就是文件,将是否是java文件的判断结果返回
return pathname.getName().toLowerCase().endsWith(".java");
}
}
// main方法
public class Demo01Filter {
public static void main(String[] args) {
File f = new File("/Users/yanzhuang/Desktop/A");
getAllFiles(f);
}
public static void getAllFiles(File pathname){
File[] files = pathname.listFiles(new FileFilterImpl());// 传递过滤器
// 遍历File数组
for (File file : files) {
// 判断file对象是文件夹还是文件
if(file.isDirectory()){
// 如果File对象是目录的话,继续递归调用自身
getAllFiles(file);
}
else {
// 不是目录的话就是.java文件,打印输出
System.out.println(file);
}
}
}
}
使用匿名内部类简化:
public class Demo02Filter {
public static void main(String[] args) {
File f = new File("/Users/yanzhuang/Desktop/A");
getAllFiles(f);
}
public static void getAllFiles(File pathname){
// 传递过滤器FileFilter,使用匿名内部类方式
File[] files = pathname.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
// 过滤规则,pathname是文件夹或者是.java结尾的文件返回true
return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
}
});
// 遍历File数组
for (File file : files) {
// 判断file对象是文件夹还是文件
if(file.isDirectory()){
// 如果File对象是目录的话,继续递归调用自身
getAllFiles(file);
}
else {
// 不是目录的话就是.java文件,打印输出
System.out.println(file);
}
}
}
}
使用Lambda表达式进一步简化:(接口都只有一个抽象方法)
public class Demo03Filter {
public static void main(String[] args) {
File f = new File("/Users/yanzhuang/Desktop/A");
getAllFiles(f);
}
public static void getAllFiles(File pathname){
// 传递过滤器FileFilter,使用匿名内部类方式,Lambda表达式
File[] files = pathname.listFiles(dir -> dir.isDirectory() || dir.getName().toLowerCase().endsWith(".java"));
// 遍历File数组
for (File file : files) {
// 判断file对象是文件夹还是文件
if(file.isDirectory()){
// 如果File对象是目录的话,继续递归调用自身
getAllFiles(file);
}
else {
// 不是目录的话就是.java文件,打印输出
System.out.println(file);
}
}
}
}
2、java.io.FilenameFilter
作用: 用于过滤文件的方法
抽象方法:用来过滤文件的方法boolean accept(File dir, String name) 测试指定文件夹是否应该包含在某一文件列表中。参数:
File dir–构造方法中传递的被遍历的目录
String name–使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称
使用匿名内部类方式:
public class Demo02Filter {
public static void main(String[] args) {
File f = new File("/Users/yanzhuang/Desktop/A");
getAllFiles(f);
}
public static void getAllFiles(File pathname){
// 传递过滤器FilenameFilter,使用匿名内部类方式
File[] files = pathname.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
}
});
// 遍历File数组
for (File file : files) {
// 判断file对象是文件夹还是文件
if(file.isDirectory()){
// 如果File对象是目录的话,继续递归调用自身
getAllFiles(file);
}
else {
// 不是目录的话就是.java文件,打印输出
System.out.println(file);
}
}
}
}
FilenameFilter过滤器也可以使用Lambda表达式进行简化:
// 传递过滤器FilenameFilter,使用Lambda表达式简化
File[] files = pathname.listFiles((dir,name) ->
new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java"));



