繁体   English   中英

奇怪的Java递归代码

[英]Strange Java Recursion Code

我有一个代码片,并且很难理解这种递归模式。

private void indexDirectory(IndexWriter indexWriter, File dataDirectory,
                            String suffix) throws IOException {

    System.out.println("Data directory before: " + dataDirectory.getName());
    File[] files = dataDirectory.listFiles();

    for (File file : files) {
        System.out.println("File name : " + file.getName());
        if (file.isDirectory()) {
            indexDirectory(indexWriter, file, suffix);
        } else {
            indexFileWithIndexWriter(indexWriter, file, suffix);
        }
    }
    System.out.println("Data directory : " + dataDirectory.getName());
}

dataDirectory包含一个目录的路径,其中有多个子目录和文件。

所以files []数组看起来像,

C:\projects\test\.classpath, 
C:\projects\test\.project, 
C:\projects\test\.settings, 
C:\projects\test\build, 
C:\projects\test\build.xml, 
C:\projects\test\dist, 
C:\projects\test\src, 
C:\projects\test\WebContent

.classpath.project是文件,而.settings是一个包含4个文件的目录。 因此当第三次迭代进入.settings目录时,它的内部有4个文件。 因为.settings是一个目录, file.isDirectory变为 true ,并且相同的方法(indexDirectory)将使用最新的参数值调用。 所以dataDirectory值被.settings取代。 当代码执行进入循环时,它将转到else部分,因为它在.settings目录中找到了它的文件。

一旦迭代4次(因为它只有4个文件),它就会完成循环。

但奇怪的是, dataDirectory值被它所拥有的旧值替换,它开始调用之前在数组中的下一个项目(这是构建目录)。

有人可以解释我为什么会这样发生,而不是完成循环..我希望我能清楚地解释它,如果没有请问我。

非常感谢你。

当第一次调用方法indexDirectory时,它里面有8个文件(包括目录)。

因此,你的for循环for (File file : files) {将迭代至少8次。 (一种)

现在,在8个文件中,找到.settings是目录。 并且你正确理解indexDirectory使用dataDirectory = .settings调用indexDirectory 此时,状态(A)中有5次迭代正在等待

当递归调用完成时,控件到达状态(A) ,第四次迭代以dataDirectory = build开始。

堆栈帧如下:

在此输入图像描述

第2帧完成后,第1帧将恢复执行。

这就是递归的工作原理。 在循环访问顶级目录时,一切正常,直到循环遍历目录。 当它遇到一个目录时,它进入一个更深的循环,但它知道它还没有完成外部循环。 一旦它完成内部循环(以及其内部的任何其他内部循环),它就会返回并完成外部循环。

想象一下,你在一个有很多门的房间里。 当您转动门上的旋钮时,会弹出一个标记。 其中一些门通向其他房间(房屋内部较深处),但大多数只是悬挂在墙上。 你必须转动每个门把手上的旋钮。 如果它通向另一个房间,你必须转动每个门上的旋钮。 当所有的旗帜都在内室时,你可以回到外面的房间并完成转动旋钮,直到所有的旗帜都朝上。 当所有旗帜都已启动并且您回到最外层的房间时,您的工作就完成了。

心连心

一旦迭代4次(因为它只有4个文件),它就会完成循环。

但奇怪的是,dataDirectory值被它所拥有的旧值替换,它开始调用之前在数组中的下一个项目(这是构建目录)。

这正是递归应该如何工作的原因。

你在某种程度上是正确的,一旦调用indexDirectory(?, ".settings", ?)indexDirectory(?, ".settings", ?)看到了四个文件,它应该已经停止循环并终止该方法。 情况确实如此,事实上这就是发生的事情 该方法在该点完成,并且控制权返回给其调用者。

然而,调用者是另一个indexDirectory调用一个级别“更高”。 这个调用迭代了C:\\projects\\test\\ ,刚刚完成了它遇到的.settings项目的处理。 因此,一旦该方法返回,它就会继续从它之前(递归地)在.settings上调用indexDirectory

因此,正如人们所期望的那样,它然后索引C:\\projects\\test\\build ,依此类推。

为了澄清一些, dataDirectory的值并没有完全被替换 实际发生的是,这个参数有两个副本 - 一个用于两个嵌套方法调用。 内心的。 递归方法有值.settings ,外部方法有test 一旦内部方法访问了它的四个文件并返回,控制就返回到外部方法 - 其中(仍然)具有dataDirectorytest值。

您以递归方式调用indexDirectory。 因此,在完成更深层目录(在此示例中为.settings)之后,它将继续完成循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM