递归的概念、分类、注意事项
package demo01;
/*
递归:方法调用自己
递归的分类:
递归分为两种,直接递归和间接递归
直接递归成为方法自己调用自己
间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法
注意事项:
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出
在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
构造方法,禁止递归
递归的使用原理
当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归
*/
public class Demo01Recurison {
public static void main(String[] args) {
//a();
b(1);
}
/*
构造方法,禁止递归
编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错
*/
public Demo01Recurison() {
Demo01Recurison();
}
/*
在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
24339
Exception in thread "main" java.lang.StackOverflowError
*/
private static void b(int i) {
System.out.println(i);
if(i == 100000) {
return;//结束方法
}
b(++i);
}
/*
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出
Exception in thread "main" java.lang.StackOverflowError
*/
private static void a() {
System.out.println("a方法");
a();
}
}
使用递归计算1-n之间和
package demo01;
/*
练习:
使用递归计算1-n之间的和
*/
public class Demo02Recursion {
public static void main(String[] args) {
int s = sum(100);
System.out.println(s);
}
/*
定义一个方法,使用递归计算1-n之间的和
1+2+3+4+...+n
n+n-1+n-2...+1
已知:
最大值:n
最小值:1
使用递归必须明确:
1、递归的结束条件
获取到1的时候结束
2、递归的目的
获取下一个被加的数字(n-1)
*/
public static int sum(int n) {
//获取到1的时候结束
if(n == 1) {
return 1;
}
//获取下一个被加的数字
return n + sum(n-1);
}
}
练习 使用递归计算阶乘
package demo01;
/*
练习:
使用递归计算阶乘
n的阶乘:n!= n*(n-1)*...*3*2*1
S的阶乘:S! = S*(S-1)*(S-2)*(S-3)*(S-4)*
*/
public class Demo03Recursion {
public static void main(String[] args) {
int jc = jc(5);
System.out.println(jc);
}
/*
定义方法使用递归计算阶乘
S的阶乘:S! = S*(S-1)*(S-2)*(S-3)*(S-4) = 5*4*3*2*1
递归结束的条件,获取到1的时候结束
递归的目的,获取到下一个被乘的数字(n-1)
方法的参数发生变化
5,4,3,2,1
*/
public static int jc(int n) {
//获取到1的时候结束
if(n == 1) {
return 1;
}
//获取下一个被乘的数字(n-1)
return n*jc(n-1);
}
}
递归打印多级目录
package demo01;
import java.io.File;
/*
练习:
递归打印多级目录
需求:
遍历 XX文件夹,以及该文件夹下的子文件夹
*/
public class Demo04Recursion {
public static void main(String[] args) {
File file = new File("F:\\BaiduNetdiskDownload");
getAllFile(file);
}
/*
定义一个方法,参数传递File类型的目录
方法中对目录进行遍历
*/
public static void getAllFile(File dir) {
File[] files = dir.listFiles();
for (File f : files) {
System.out.println(f);
}
}
}
package demo01;
import java.io.File;
/*
练习:
递归打印多级目录
需求:
遍历 XX文件夹,以及该文件夹下的子文件夹
*/
public class Demo04Recursion {
public static void main(String[] args) {
File file = new File("F:\\BaiduNetdiskDownload");
getAllFile(file);
}
/*
定义一个方法,参数传递File类型的目录
方法中对目录进行遍历
*/
public static void getAllFile(File dir) {
System.out.println(dir);//打印被遍历的目录名称
File[] files = dir.listFiles();
for (File f : files) {
//对遍历得到的File对象进行判断,判断是否是文件夹
if(f.isDirectory()) {
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
} else {
//f是一个文件,直接打印即可
System.out.println(f);
}
}
}
}
综合案例 文件搜索
package demo01;
import java.io.File;
/*
练习:
递归打印多级目录
需求:
遍历 XX文件夹,以及该文件夹下的子文件夹
*/
public class Demo05Recursion {
public static void main(String[] args) {
File file = new File("F:\\BaiduNetdiskDownload");
getAllFile(file);
}
/*
定义一个方法,参数传递File类型的目录
方法中对目录进行遍历
*/
public static void getAllFile(File dir) {
//System.out.println(dir);//打印被遍历的目录名称
File[] files = dir.listFiles();
for (File f : files) {
//对遍历得到的File对象进行判断,判断是否是文件夹
if(f.isDirectory()) {
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
} else {
//f是一个文件,直接打印即可
/*
只要.zip结尾的文件
1、把File对象f,转换为字符串对象
*/
//String name = f.getName();
//String path = f.getPath();
String s = f.toString();
//把字符串转换为小写
//s = s.toLowerCase();
//2、调用String类中的方法endsWith判断字符串是否是以.zip结尾
//boolean b = s.endsWith(".zip");
//3、如果是以.java结尾的文件,则输出
/*if(b) {
System.out.println(f);
}*/
if(f.getName().toLowerCase().endsWith(".zip")) {
System.out.println(f);
}
}
}
}
}