[英]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
。 一旦内部方法访问了它的四个文件并返回,控制就返回到外部方法 - 其中(仍然)具有dataDirectory
的test
值。
您以递归方式调用indexDirectory。 因此,在完成更深层目录(在此示例中为.settings)之后,它将继续完成循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.