“嗨,Amigo。今天 Bilaabo 将向您介绍递归。”

如您所知,在 Java 中,一些方法会调用其他方法。此外,当一个方法被调用时,特定的参数被传递给它,但是方法的局部变量在它运行时采用特定的值。
“嗯。”
“正如你所知,不同方法的内部变量是相互独立的。”
“嗯。”
“所以想象一下方法调用自身的情况。这称为递归。例如:”
public static void main(String[] args)
{
countDown(10);
}
public static void countDown(int x)
{
if (x <= 0)
System.out.println("Boom!");
else
{
System.out.println(x);
countDown(x - 1);
}
}
10
9
8
7
6
5
4
3
2
1
Boom!
“我可以看到该方法在代码中调用了自身,但老实说我不明白发生了什么。”
“好吧,当调用不同的方法时会发生同样的事情。”
“不,我问的是变量会发生什么?它们的值会怎样?我们如何退出该方法?还是一次性退出所有内容?”
“天哪。一切都简单多了。想象一下,调用自身的方法被乘以了很多次。那么我们就会遇到类似的情况:”
递归方法调用 | 真正发生了什么 |
---|---|
|
|
屏幕输出: | 屏幕输出: |
---|---|
|
|
“换句话说,每次调用一个方法(甚至调用它自己)时,都会创建新变量来存储该方法的数据。没有共享变量。”
“每次调用时,都会在内存中创建具有新值的方法参数的另一个副本。当我们返回到旧方法时,它的变量会在那里使用。换句话说,在递归期间我们实际上调用了另一个方法,但是使用和我们的代码一样! ”
“我明白了。退出这种方法是如何工作的?也许是一个例子?”
“好的。一个例子胜过一千个字。”这是你的例子:
递归方法调用 | 递归方法调用 |
---|---|
|
|
屏幕输出: | 屏幕输出: |
---|---|
|
|
“好的。我想我明白了。为什么我们需要递归?”
“有很多很多任务可以分成与原始任务相同的单独子任务。例如,您需要遍历 XML 树的所有元素。每个元素可以有几个子元素,它们有自己的子元素自己的子元素。”
“或者你需要显示一个目录及其所有子目录中的文件列表。所以你写了一个方法来显示当前目录的文件。然后要获取所有子目录的文件,你调用你的方法使用不同的论点:一个子目录。”
“例如:”
public static void main(String[] args)
{
printAllFiles(new File("c:/windows/"));
}
public static void printAllFiles(File dir)
{
for (File file : dir.listFiles())
{
if (file.isDirectory())
printAllFiles(file);
else
System.out.println(file.getAbsolutePath());
}
}
“第 8 行——我们获取 dir 目录中所有文件(和目录)的列表。”
“第 10-11 行——如果文件实际上是一个目录,那么我们再次调用printAllFiles,但这次有另一个参数:子目录。”
“第 13 行——我们显示当前文件的名称。”
“好的。我想我明白了。谢谢你,Bilaabo。”
GO TO FULL VERSION