DeveloperForce
DeveloperForce

Reputation: 50

Using download percentage to implement Java recursion

Public class JavaRecursion {
  static void downloadStatus(int percentage) {
    System.out.println("download is at " + percentage + "%\n"):

          downloadIncrease();
  }

  Static void downloadIncrease() {
    Int speed = 0;

    While(speed < 100) {
      speed++;

      downloadStatus(speed);
    }

    Public static void main(String[] args) {
      downloadIncrease();
    }

  } // closing the class bracket

So I want to implement recursion where two function calls each other repeatedly

Download increase adds speed which gets passed as an argument to percentage parameter in downloadStatus method

So the idea is for every increases in download speed, downloadstatus method would be called to print the update and then downloadincrease would be called to increase the download percentage again etc

This would basically go on until download percentage reaches 100%

I've checked the logic for my loop statement and it works because immediately I stopped calling one method from the other, the whole thing printed to 100% without error, but I specifically want one method to do the download increase and another to print the update statement, and for them to keep calling each other until download reaches 100%

But I keep getting stackoverflow error and the code prints "the download is at 1%" several times before throwing this error, what am I doing wrong???

Can anyone advise?

Upvotes: -4

Views: 126

Answers (4)

Abra
Abra

Reputation: 20913

The code in your question does not compile.

  • Java is case-sensitive
    • access modifier is public (and not Public)
    • Static should be static
    • Int should be int
    • While should be while
  • First line in body of method downloadStatus is terminated with a colon (:) rather than a semi-colon (;)
  • You are missing a closing bracket (}) in method downloadIncrease.

Is that your actual code?

The problem with your code is, in the first iteration of the while loop (in method downloadIncrease) methods downloadIncrease and downloadStatus call each other infinitely. In other words, the while loop is only ever iterated once. And since the methods call each other infinitely, eventually the call stack fills up and you get StackOverflowError. That's why

the code prints "the download is at 1%" several times before throwing this error

(As you wrote in your question.)

If you are using an IDE – such as Eclipse or IntelliJ – then run your code using the debugger of the IDE to verify my explanation of the problem with your code.

Hence the while loop is not the correct way to terminate recursion. Rather you need an if, i.e.

if (speed < 100)

However, this will still not solve your problem since in each call to method downloadIncrease you are re-setting speed to 0 (zero). speed needs to be a method parameter and the first time you call method downloadIncrease (from method main) you should pass 0 as the value for speed.

Here is your code with my corrections.

public class JavaRecursion {

    static void downloadStatus(int percentage) {
        System.out.println("download is at " + percentage + "%");
        downloadIncrease(percentage);
    }

    static void downloadIncrease(int speed) {
        if (speed < 100) {
            speed++;
            downloadStatus(speed);
        }
    }

    public static void main(String[] args) {
        downloadIncrease(0);
    }
}

Here is output from a sample run.

download is at 1%
download is at 2%
download is at 3%
download is at 4%
download is at 5%
download is at 6%
download is at 7%
download is at 8%
download is at 9%
download is at 10%
download is at 11%
download is at 12%
download is at 13%
download is at 14%
download is at 15%
download is at 16%
download is at 17%
download is at 18%
download is at 19%
download is at 20%
download is at 21%
download is at 22%
download is at 23%
download is at 24%
download is at 25%
download is at 26%
download is at 27%
download is at 28%
download is at 29%
download is at 30%
download is at 31%
download is at 32%
download is at 33%
download is at 34%
download is at 35%
download is at 36%
download is at 37%
download is at 38%
download is at 39%
download is at 40%
download is at 41%
download is at 42%
download is at 43%
download is at 44%
download is at 45%
download is at 46%
download is at 47%
download is at 48%
download is at 49%
download is at 50%
download is at 51%
download is at 52%
download is at 53%
download is at 54%
download is at 55%
download is at 56%
download is at 57%
download is at 58%
download is at 59%
download is at 60%
download is at 61%
download is at 62%
download is at 63%
download is at 64%
download is at 65%
download is at 66%
download is at 67%
download is at 68%
download is at 69%
download is at 70%
download is at 71%
download is at 72%
download is at 73%
download is at 74%
download is at 75%
download is at 76%
download is at 77%
download is at 78%
download is at 79%
download is at 80%
download is at 81%
download is at 82%
download is at 83%
download is at 84%
download is at 85%
download is at 86%
download is at 87%
download is at 88%
download is at 89%
download is at 90%
download is at 91%
download is at 92%
download is at 93%
download is at 94%
download is at 95%
download is at 96%
download is at 97%
download is at 98%
download is at 99%
download is at 100%

Upvotes: 1

Idle_Mind
Idle_Mind

Reputation: 39142

Instead of the two methods calling each other, I'd make your status method simply output and then return. Additionally, make the speed a parameter so that you can pass it in the recursive call. The recursion takes the place of the while loop.

With all that in mind, it could look something like:

  public static void main(String[] args) {    
    downloadIncrease(0);
  } 

  public static void downloadIncrease(int speed) {   
    if (speed <= 100) {
      downloadStatus(speed);
      downloadIncrease(speed+1);
    }
  }

  static void downloadStatus(int percentage) {
    System.out.println("download is at " + percentage + "%\n");
  }

Upvotes: 1

Gilbert Le Blanc
Gilbert Le Blanc

Reputation: 51565

I fixed the syntax errors and made a few changes. Here are the results of a test run.

download is at 1%

download is at 2%

download is at 3%

download is at 4%

download is at 5%

download is at 6%

download is at 7%

download is at 8%

download is at 9%

download is at 10%

...

download is at 90%

download is at 91%

download is at 92%

download is at 93%

download is at 94%

download is at 95%

download is at 96%

download is at 97%

download is at 98%

download is at 99%

download is at 100%

Here's the revised code.

public class JavaRecursion {

    static void downloadStatus(int percentage) {
        System.out.println("download is at " + percentage + "%\n");
        downloadIncrease(percentage);
    }

    static void downloadIncrease(int speed) {
        if (speed >= 100) {
            return;
        }
        speed++;
        downloadStatus(speed);
    }

    public static void main(String[] args) {
        int speed = 0;
        downloadIncrease(speed);
    }

}

The int speed has to be defined outside of the recursion. For a recursion to work, there must be an end condition that returns through the recursion stack.

Since you tagged Swing, Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Concurrency in Swing section.

Upvotes: 1

EH.Lee
EH.Lee

Reputation: 11

When downloadIncrease() method called by the downloadStatus() method, the speed become 0 and it never end. I suggest that you should not use recursion and just call the downloadStatus() to print out.

If you really want to keep the recursion, you may set the speed as global variable like below

class Main {
static int speed = 0;

static void downloadStatus(int percentage) {
    System.out.println("Download is at " + percentage + "%\n");
    downloadIncrease();
}

static void downloadIncrease() {
    while(speed < 100) {
        speed++;
        downloadStatus(speed);
    }
}

public static void main(String[] args) {
    downloadIncrease();
}}

But please notice, this still possible to create the overflow. The best way I believe is below

class Main {
  static void downloadStatus(int percentage) {
    System.out.println("download is at " + percentage + "%\n");
  }

  static void downloadIncrease() {
    int speed = 0;

    while(speed < 100) {
      speed++;
      downloadStatus(speed);
    }
  }

  public static void main(String[] args) {
    downloadIncrease();
  }
}

Upvotes: 1

Related Questions