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();