Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive method returning empty value

Tags:

java

recursion

Description

My goal is to store all file paths in a file. To do that I built a recursive method which browse a specific folder. However, the result is still empty ...

Code

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;
}

All files are displayed in the console thanks to the sysout. However, my result file is empty.

Any idea ? Thank you.

like image 294
Royce Avatar asked Apr 20 '26 15:04

Royce


2 Answers

Due to immutability of String (variable result always references the same string value in memory), you should use concat to save the result, as it actually creates a new reference to a new string value.

if (fileEntry.isDirectory()) {
    result += browseFolder(result, fileEntry);
}
like image 135
Steyrix Avatar answered Apr 23 '26 04:04

Steyrix


Note that the recursive call to browseFolder will not change its parameter, because String is immutable. A string variable that is passed to a method will always stay the same after that method returns. This means that as long as the blablalbla/.../toto directory is full of subdirectories, your main call to browseFolder will return an empty string, because you are not doing anything to result.

You could append the return value of recursive browseFolder calls to result, like this:

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;
}

However, this creates a new string every time you do this, so it is quite wasteful. You can use a StringBuilder (which is mutable!) instead.

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;
}

The caller will have to change too. You can do .toString on a StringBuilder to convert it to String.

String files = browseFolder(new StringBuilder(), new File("blablalbla/.../toto")).toString();
like image 23
Sweeper Avatar answered Apr 23 '26 04:04

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!