java基础 ---- 递归,过滤器接口
递归的理解概述:
-
递归指自己调用自己。直接递归:方法自身调用自己;间接追归:A方法调用B方法,B方法调用C方法,C方法调用A方法。
-
当一个方法调用其他方法的时候被调用的方法没有执行完毕,当前方法会一直等待调用的方法执行完毕才会继续执行。
递归的使用概述:
- a方法会在内存中一直调用a方法就会导致内存中有无数多个a方法,方法太多了超出栈内存的大小就会导致内存溢出的错误。比如:调用次数过多,没有设置退出调用的条件等。
过滤器接口的理解概述:
- File类中的listFile()有两个重载方法分别是listFiles(FileFilter),listFiles(FilenameFilter),其中FileFilter,FilenameFilter是过滤器接口,都只包含一个方法分别是accept(File pathname),accept(File dir,String name),功能是过滤掉不符合accept方法中规则的File对象。
- listFiles(FileFilter )的执行流程:
1.listFiles方法对构造方法File file = new File(pathname:"...")中传递的目录进行遍历,获取目录中的每个一个文件/文件夹-->封装为File对象
2. listFiles方法会调用参数传递的过滤器中的方法 accept
3. listFiles方法会把遍历得到的每一个File別象,传递给accept方法的参数 pathname
4.accept方法返回值是布尔值:true就会把传递过去的File对象保存到File数组中;反之,不会。
注意:listFiles(FilenameFilter)对应地应该对File file = new File(File dir:"...",String name:"...");这种构造方法。
过滤器接口的使用概述:
- 因为过滤器接口只有一个方法需要重写,所以方便直接用匿名内部类兼匿名对象实现,或者直接用Lambda表达式实现。
递归,过滤器接口的测试代码:
package com.baishi.stage1.day10;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
/**
*创建过滤器FileFilter接口的实现类
*重写过滤方法accept,定义过滤规则:
*如果File对象是一个文件夹,或者File对象是否是以.java结尾:是就返回true
*否则就返回false
*/
class FileFilterImpl implements FileFilter {
@Override
public boolean accept(File pathname) {
//
if(pathname.isDirectory()){
return true;
}
//
return pathname.getName().toLowerCase().endsWith(".java");
}
}
/**
*创建FilenameFilter接口的实现类
*重写accept方法:
* 如果参数对应的文件是文件夹,或者是以.java结尾就返回true
* 否则就返回false*/
class FilenameFilterImpl implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
}
}
public class MyTest {
/*构造方法,禁止递归*/
//public MyTest() {
// MyTest();// 编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错
//}
public static void main(String[] args) {
show1(0);
show2();
show3();
show4();
show5();
}
/**
* show1():
* 测试递归依次打印上限较大的数
*/
public static void show1(int i) {
/*在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出*/
System.out.println(i);
if (i == 20000) {
return; //结束方法
}
show1(++i);
}// Exception in thread "main" java.lang.StackOverflowError
/**
*show2()
*测试无退出递归命令
*/
public static void show2() {
/*递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出*/
System.out.println("show2方法!");
show2();
}// Exception in thread "main" java.lang.StackOverflowError
/**
*show3():递归遍历多级文件夹并筛选出特定类型的文件
*调用listFiles()方法将文件返回一个File数组存储该File目录中的所有的子文件或目录;
* 增强for循环遍历File[]数组:
* 判断是文件夹就继续遍历,
* 是文件就将文件名转换成字符串并转换成小写,并判断是java结尾就打印。
*/
public static void show3() {
File file = new File("c:\\abc");
getAllFile(file);
}
public static void getAllFile(File dir){
File[] files = dir.listFiles();
//
for(File f : files){
if(f.isDirectory()){
getAllFile(f);
}else{
String name = f.getName();//getName()把File对象名称
//String path = f.getPath(); 获取File对象完整路径
//String s = f.toString();
//
name = name.toLowerCase();//toLowerCase()把字符串转换成小写
boolean b = name.endsWith(".java");//endsWith(String:"...")调用String类中的方法endsWith判断字符串是否是以.java结尾
if(b){
System.out.println(f);
/*链式编程:
if(f.getName().toLowerCase().endsWith(".java")){
System.out.println(f);
}*/
}
}
}
}
/**
*show4():测试FileFilter过滤器遍历多级文件夹并筛选出特定类型的文件
*调用listFiles(FileFilter:...)方法将文件返回一个File数组存储该File目录中的经过过滤器后的子文件或目录;
*增强for循环遍历文件夹:
*判断是文件夹继续遍历,
*是文件名直接打印。
*/
public static void show4() {
File file = new File("c:\\abc");
getAllFile2(file);
//
}
public static void getAllFile2(File dir){
File[] files = dir.listFiles(new FileFilterImpl());//过滤器匿名对象
//
for (File f : files) {
if(f.isDirectory()){
getAllFile(f);
}else{
System.out.println(f);
}
}
/*使用匿名对象:
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
}
});*/
/*使用Lambda表达式:
File[] files = dir.listFiles((File pathname)->{
return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
});*/
// File[] files = dir.listFiles(pathname->pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java"));
}
/**
*show5():测试FilenameFilter过滤器遍历多级文件夹并筛选出特定类型的文件
*调用listFiles(FilenameFilter:...)方法将文件返回一个File数组存储该File目录中的经过过滤器后的子文件或目录;
*增强for循环遍历文件夹:
*判断是文件夹继续遍历,
*是文件名直接打印。
*/
public static void show5() {
File file2 = new File("C:\\","abc");
getAllFile3(file2);
}
public static void getAllFile3(File dir){
File[] files = dir.listFiles(new FilenameFilterImpl());//过滤器匿名对象
//
for (File f : files) {
if(f.isDirectory()){
getAllFile(f);
}else{
System.out.println(f);
}
}
} /*使用匿名对象:
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
}
});*/
/*使用Lambda表达式:
File[] files = dir.listFiles((File d, String name)->{
return new File(d,name).isDirectory() || name.toLowerCase().endsWith(".java");
});*/
//File[] files = dir.listFiles((d,name)->new File(d,name).isDirectory() || name.toLowerCase().endsWith(".java"));
}