Java 返回空值的递归方法

Java 返回空值的递归方法,java,recursion,Java,Recursion,说明 我的目标是将所有文件路径存储在一个文件中。为此,我构建了一个递归方法来浏览特定的文件夹。然而,结果仍然是空的 代码 public void main(String[] args) { String files = browseFolder("", new File("blablalbla/.../toto")); FileWriter writer = new FileWriter(new File("result/")); writer.write(files)

说明

我的目标是将所有文件路径存储在一个文件中。为此,我构建了一个递归方法来浏览特定的文件夹。然而,结果仍然是空的

代码

public void main(String[] args) {
    String files = browseFolder("", new File("blablalbla/.../toto"));

    FileWriter writer = new FileWriter(new File("result/"));
    writer.write(files);
    writer.close();
}

private static String browseFolder(String result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result += fileEntry.getPath() + "\n";
        }
    }
    return result;
}
由于使用了
sysout
,所有文件都显示在控制台中。但是,我的结果文件是空的


有什么想法吗?谢谢。

由于
字符串
的不变性(变量
结果
总是在内存中引用相同的字符串值),您应该使用concat保存结果,因为它实际上创建了对新字符串值的新引用

if (fileEntry.isDirectory()) {
    result += browseFolder(result, fileEntry);
}

您忽略了递归方法返回的
字符串
,这就是为什么最后会得到一个空的
字符串

我建议您向递归方法传递一个
StringBuilder
,而不是连接
String
s,这会导致创建许多
String
实例

这样,您的方法就可以修改
StringBuilder
,而不必返回值

public void main(String[] args) {
    StringBuilder files = new StringBuilder();
    browseFolder(files, new File("blablalbla/.../toto"));

    FileWriter writer = new FileWriter(new File("result/"));
    writer.write(files.toString());
    writer.close();
}

private static void browseFolder(StringBuilder result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        } else {
            System.out.println(fileEntry.getPath());
            result.append(fileEntry.getPath()).append("\n");
        }
    }
}

请注意,对
browseFolder
的递归调用不会更改其参数,因为
String
是不可变的。传递给方法的字符串变量在该方法返回后将始终保持不变。这意味着,只要
blablalbla/../toto
目录充满子目录,您对
browseFolder
的主调用将返回一个空字符串,因为您没有对
结果执行任何操作

您可以将递归
浏览文件夹
调用的返回值附加到
结果
,如下所示:

private static String browseFolder(String result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            // here:
            result += browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result += fileEntry.getPath() + "\n";
        }
    }
    return result;
}
但是,每次这样做时都会创建一个新字符串,因此这是非常浪费的。您可以使用
StringBuilder
(它是可变的!)

打电话的人也得换电话。您可以在
StringBuilder
上执行
.toString
,将其转换为
String

String files = browseFolder(new StringBuilder(), new File("blablalbla/.../toto")).toString();

在方法体中为参数赋值被认为是一个坏主意。对于这个问题,您可能应该阅读@ernest_k的答案谢谢。您是否认为这就是我面临此错误的原因:
线程“main”java.lang.OutOfMemoryError中的异常:java堆空间
否。如果您使用
“/”
(或
“C:\”
)作为
文件夹调用您的方法,我想您可能会遇到该错误
private static StringBuilder browseFolder(StringBuilder result, File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            browseFolder(result, fileEntry);
        }
        else {
            System.out.println(fileEntry.getPath());
            result.append(fileEntry.getPath()).append("\n");
        }
    }
    return result;
}
String files = browseFolder(new StringBuilder(), new File("blablalbla/.../toto")).toString();