1

私はコード片を持っていて、この再帰パターンを理解するのに本当に苦労しています。

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 つのファイルを含むディレクトリです。そのため、3 回目の反復で.settingsディレクトリが呼び出され、その中に 4 つのファイルが含まれています。.settings はディレクトリであるため、file.isDirectorytrue になり、同じメソッド (indexDirectory) が最新のパラメータ値で呼び出されます。したがって、dataDirectory値は .settings に置き換えられます。コードの実行がループに入ると、 .settingsディレクトリ内にファイルが見つかったため、 else部分に移動します。

4回反復すると(ファイルが4つしかないため)、ループを終了することになります。

しかし奇妙なことに、 dataDirectoryの値が古い値に置き換えられ、以前に配列にあった次の項目 (ビルドディレクトリ) を呼び出し始めます。

ループを終了せずに、なぜそのようなことが起こったのか、誰か説明してもらえますか..明確に説明したいと思います。

どうもありがとうございました。

4

4 に答える 4

3

メソッドindexDirectoryを初めて呼び出すと、内部に8つのファイル(ディレクトリを含む)があります。

したがって、forループfor (File file : files) {は少なくとも8回繰り返されます。(A)

これで、8つのファイル内に、ディレクトリである.settingsが見つかりました。そして、あなたはそれが復活することを正しく理解しましたindexDirectory-dataDirectory=.settingsで呼び出します。この時点で、状態(A)から5回の反復が保留中です。

再帰呼び出しが完了すると、コントロールは状態(A)に到達し、4回目の反復はdataDirectory=buildで始まります。

スタックフレームは次のようになります。

ここに画像の説明を入力してください

フレーム2が完了すると、フレーム1は実行を再開します。

于 2012-10-22T11:30:49.020 に答える
1

これが再帰の仕組みです。トップレベルのディレクトリをループしている間、ループがディレクトリに到達するまで、すべてが正常に機能します。ディレクトリに出くわすと、より深いループに入りますが、外側のループが終了していないことを認識しています。内側のループ(およびその内側のそれ以上の内側のループ)が終了すると、元に戻って外側のループを終了します。

あなたがたくさんのドアのある部屋にいると想像してみてください。ドアのノブを回すと、旗がポップアップします。これらのドアのいくつかは他の部屋(家の奥深く)に通じていますが、ほとんどは壁にぶら下がっています。各ドアハンドルのノブを回す必要があります。別の部屋に開く場合は、それらの各ドアのノブも回す必要があります。すべての旗が内側の部屋に上がったら、外側の部屋に戻って、すべての旗が上がるまでノブを回し終えることができます。すべての旗が上がって、あなたが一番外側の部屋に戻ったら、あなたの仕事は終わりです。

hth

于 2012-10-22T11:32:05.987 に答える
0

4回反復すると(ファイルが4つしかないため)、ループを終了することになります。

しかし奇妙なことに、dataDirectory の値が古い値に置き換えられ、以前に配列にあった次の項目 (ビルド ディレクトリ) を呼び出し始めます。

これはまさに、再帰が機能するはずの方法です。

indexDirectory(?, ".settings", ?)の呼び出しで4 つのファイルが表示されると、ループが停止し、メソッドが終了するはずだったというのは、ある程度正しいことです。それは事実であり、実際にこれが起こったことです。メソッドはその時点で終了し、制御は呼び出し元に戻りました。

ただし、発信者はindexDirectory「より高い」レベルの別の通話でした。 この呼び出しは 内のアイテムを反復処理しており、遭遇C:\projects\test\したアイテムの処理を終えた.settingsところです。indexDirectoryしたがって、そのメソッドが返されると、(再帰的に) on が呼び出される前の場所から続行され.settingsます。

したがって、予想されるように、次にインデックスが付けC:\projects\test\buildられます。

さらに明確にするために、の値はdataDirectory正確に置き換えられていませんでした。実際に起こったことは、一度にこの引数の 2 つのコピーがあったことです。つまり、ネストされた 2 つのメソッド呼び出しのそれぞれに 1 つです。内部。再帰メソッドの値.settingsは で、外側のメソッドの値は でしたtest。内側のメソッドが 4 つのファイルにアクセスして戻ると、制御は外側のメソッドに戻りました。これには (まだ) testforの値がありましたdataDirectory

于 2012-10-22T11:29:57.163 に答える
0

indexDirectory を再帰的に呼び出しています。したがって、より深いディレクトリ (この例では .settings ) を終了した後、ループを終了し続けます。

于 2012-10-22T11:34:45.677 に答える