Jakub Piechowiak
Jakub Piechowiak

Reputation: 3

Recursive mean of files size [JAVA]

I wrote a function that reads all files and adds them to arraylist which looks like this:

ArrayList<File> files = new ArrayList<File>();

I need to calculate aritmethic mean of the size(in bytes) of all the files in ArrayList.

Considering that these are plenty of files I decided to make mean function recursive.

I got something like this:

public static Double mean(ArrayList<File> files) {
    if(files.size() == 1) {
      return Double.valueOf(files.get(0).length());
    }
    else {
      int _removed = (int) files.remove(files.size() - 1).length();
      return Double.valueOf(mean(files) + _removed / files.size());
    }
  }

But I'm doing something wrong becouse it causes StackOverflowError. How to write this function properly?

Upvotes: 0

Views: 97

Answers (3)

Hubblenaut
Hubblenaut

Reputation: 86

Since you're performing operations on the returned value of your recursive call, your stack of resursively called operations cannot be resolved until the program reached the end of it.

In your case however, there is no advantage using recursive calls than using a simple loop especially when dealing with large data structures:

public static Double mean(ArrayList<File> files) {
    Double sum = 0;
    for (File file : files) {
        sum += file.length();
    }
    return sum / files.size();
}

Upvotes: 0

Jan B.
Jan B.

Reputation: 6448

For all those with the intrinsic desire to implement every loop with the Stream API:

double mean = files.stream().mapToLong(File::length).sum() / files.size();

Thanks to the commenters Olivier and Johannes for an even simpler solution:

OptionalDouble mean = files.stream().mapToLong(File::length).average();

Upvotes: 3

GBlodgett
GBlodgett

Reputation: 12819

You probably shouldn't use recursion in this case. Doing so pushes a lot of things on the stack and makes it prone to the Stack Overflow error. It would be better to use an enhanced for loop.

long totalSum =0;
for(File file: files) {
     totalSum += file.length();
}  
return Double.valueOf(totalSum / files.size());

Upvotes: 2

Related Questions