Recursion - why use return statement - java

I am learning recursion and below is one example that I am tracing through to better understand it
public static void main(String []args) {
new TestRecursion().strRecur("abc");
}
public void strRecur(String s) {
if(s.length() < 6) {
System.out.println(s);
strRecur(s+"*");
}
}
Below is what I have understood so far.
- In the first call to strRecur("abc"), the method gets added to execution stack. It prints "abc" before pausing due to a recursive call with parameter "abc*".
The second call with "abc*", pushes method strRecur(abc*) to the stack and prints "abc*" to console.
The third call with "abc**", pushes method strRecur(abc**) to the stack and prints "abc**" to console.
The fourth call with "abc***", pushes method strRecur(abc***) to the stack. Since the base condition is met, the method completes (without printing anything) and pops out of the stack.
The third call with "abc**" is completed and popped out. Since there is no pending code to execute nothing happens.
The second call with "abc*" is completed and popped out. Since there is no pending code to execute nothing happens.
The initial call with "abc" is completed and popped out. Since there is no pending code to execute nothing happens.
Prints following to the console -
abc
abc*
abc**
I think I understand what is happening here. Now, I want to try a slight variation of this code. Instead of callingstrRecur(s+"*"), I would like to do return strRecur(s+"*")
public class TestRecursion {
public static void main(String []args) {
new TestRecursion().strRecur("abc");
}
public String strRecur(String s) {
if(s.length() < 6) {
System.out.println(s);
return strRecur(s+"*");
}
return "Outside If";
}
}
My expectation was that, once strRecur(abc***) pops out, it's output (abc***) would be returned to the next strRecur() on the stack, so I would see abc**** printed in the console. Same for other recursive calls as well.
However, the output in this case is exactly the same as when there is no return statement. My understanding (which of course is not correct) stems from the recursive factorial implementation, where we do something like
return n * fact(n-1);
Here fact(n-1) is resolved with the returned value of n, once the previous method on the stack completes. Why doesn't return behave in the same way in this example?

The output of both methods is produced by the println statements within the recursive method, which is why it is identical in both methods.
The value returned by the second method is not printed anywhere, which is why you don't see it displayed.
If you would print the result of the second method, you will see it is "Outside If", since that's the output of the last recursive call, which is then returned by all the other method calls.
If you want the output to be abc***, you should
return s;
instead of
return "Outside If";
The full code would be:
public static void main(String[] args) {
System.out.println(new TestRecursion().strRecur("abc"));
}
public String strRecur(String s) {
if(s.length() < 6) {
return strRecur(s+"*");
}
return s;
}

Here is how to make it return the value instead of printing it:
public static void main(String[] args) {
String result = StrRecur("abc");
System.out.print(result);
}
public static String StrRecur(String s) {
if(s.length() < 6) {
return s + "\n" + StrRecur(s+"*");
}
return "";
}
This does the same, but the side effect happens only in main.

Related

Java recursive method difference

What is the difference between the following two methods:
public boolean recursionMethodOne(Node n) {
System.out.println(n.getValue());
return recursionMethodOne(n.next());
}
public void recursionMethodTwo(Node n) {
System.out.println(n.getValue());
recursionMethodTwo(n.next());
}
Which one do you use for recursion and what is the difference?
Thanks
Both your codes doesn't exits. You need to add a return for a test condition. For example:
public void recursionMethodTwo(Node n) {
if (n == null) {
// Standard way to exit a void function without executing remaing code
// note that return null; doesn't compile
return;
}
System.out.println(n.getValue());
recursionMethodTwo(n.next());
}
Returning a value or not depends on the kind of function.
For example if you need to calculate a factorial you need a result, if you need to print a list you don't.
So for your example seems that the method two is most closer to your needs.
Otherwise you need to ask yourself what is the returning boolean value of the function? If you have a nice answer to this question you can implement the code returning a value.

Conditional Breakpoints on Call Stack with Netbeans and Java

Just like this question, when debugging an application, I want to let the application pause at a breakpoint only when the current call stack has a certain method. However, I'm using Netbeans.
In Java the current call stack could be obtained in several ways, like
Thread.currentThread().getStackTrace()
which returns an array of stack trace elements.
Is it possible to iterate through the array (or converted list), check the method names and return a boolean in just one line?
Or, if I need to write a method which checks the array and returns the boolean based on existence of interested method, where should I put it?
For my specific requirement, using lambda and stream in Java 8:
Arrays.asList(Thread.currentThread().getStackTrace())
.stream()
.anyMatch(e -> e.getMethodName().contains("fetchByABC"))
You can add a private method testing conditions on the stack and call it from the conditional breakpoint. Here is a proof of concept:
public class DebugStack {
private int x = 0;
private void m1(){
x++;
m2();
}
private void m2(){
x+=3;
}
private boolean insideMethod(String methodName){
for (StackTraceElement stackTrace : Thread.currentThread().getStackTrace()) {
if (stackTrace.getMethodName().equals(methodName)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
DebugStack dbg = new DebugStack();
dbg.m1();
dbg.m2();
}
}
If you put a conditional breakpoint inside m2() with this.insideMethod("m1") as a condition the application will pause at the breakpoint only when m2() is called from within m1().

Return statement not working when calling another method

I have recently started experimenting with the return statement, and I have a small doubt relating to it- When I have a method which calls another method, will the return statement of that method which I am calling be displayed?
Let be give an example to make it clearer-
/** Program to test return statment */
public class Test
{
public static void main(int a)
{
EvenOrOdd(a);
}
private static boolean EvenOrOdd(int a)
{//I can declare as public and run directly but then what is the point in calling the method?
if(a%2==0)
{
System.out.println("The output is true.");//Displays
return true;//Does not display(As in that window does not pop up with the result.)
}
else
{
System.out.println("The output is false.");//Displays
return false;//Does not display
}
}
}
If I were to simply remove the main method(or even make the second method public and run that directly), my return statement is displayed however if I attempt to call the method and run the program my return statement isn't displayed.
So is this just a problem I am facing or is it a general rule in Java that the return statement doesn't work when you call another method(which has a return statement)?
If it is the latter, then I apologise, I was not aware of this.
Thanks...
***UPDATE***
It seems that nobody has understood what I exactly mean. I will give another example-
Please run this program-:
/** Program to test Return statment;simple program to return sum of two digits */
public class Return_Test
{
public static int main(int a,int b)
{
return a+b;//What I am lloking for is that box in which this is displayed.
}
}
A return statement only returns the value ,does not Display it
If you don’t catch the return value , how can it be displayed? add something like this and try
,
public class Test
{
public static void main(int a)
{
boolean temp=EvenOrOdd(a);
if(temp)
System.out.println("Output is True");
else
System.out.println("Output False(not even )");
//Or you can directly call the method as' System.out.println(EvenOrOdd));'
}
private static boolean EvenOrOdd(int a)
{//I can declare as public and run directly but then what is the point in calling the method?
if(a%2==0)
{
System.out.println("The output is true.");//Displays
return true;//Does not display
}
else
{
System.out.println("The output is false.");//Displays
return false;//Does not display
}
}
}
And Please try learning some good Naming Conventions , Classes are Named like this ,
FirstSecond,TestException(Each Word Starts with a Capital Letter) etc , methods start with a small letter , isPrime() , isEven(),
What a lot of other responders don't know is that when you run a method in BlueJ, it executes the method, and if the the return value of the method is non-void, it is shown in a popup dialog by invoking toString. That's what the questioner means by the value being displayed.
The answer to the user's original question is that by surrounding the method with a void return, it "hides" the result. So this code:
public void callMe1(int a)
{
EvenOrOdd(a);
}
will not display the return. But if you adjust the return type and actually return the value of the inner call:
public int callMe2(int a)
{
return EvenOrOdd(a);
}
Then BlueJ will display the returned value. The display aspect is down to BlueJ, but the rules for whether or not the value gets returned are the same as in Java; void means no return.
Within the body of the method, you use the return statement to return the value. It will not print anything on its own.
Changes done - System.out.println(EvenOrOdd(5));
public class Test {
public static void main(String[] args) {
System.out.println(EvenOrOdd(5));
}
private static boolean EvenOrOdd(int a) {// I can declare as public and run directly but then what is the point in
// calling the method?
if (a % 2 == 0) {
System.out.println("The output is true.");// Displays
return true;// Does not display
} else {
System.out.println("The output is false.");// Displays
return false;// Does not display
}
}
}
Output
The output is false.
false
You never actually display the return result from the method...
The name of the method is consuming EvenOrOdd returning true or false is ambigious, may isEven would be better...
You could try something like...
System.out.println(a + " is even = " + EvenOrOdd(a));
You should also avoid using multiple return statements within a single method, it can quickly become confusing as to how the method actually works, in your case, you can reduce the over complexity at the same time, for example...
private static boolean isEven(int a)
{
boolean isEven = false;
if(a%2==0)
{
System.out.println("The output is true.");//Displays
isEven = true;//Does not display
}
return isEven;
}
first change your main signature from main(int a) to main(String [] args) otherwise you will get following runtime exception :
Error: Main method not found in class yourpackagename.Test, please define the main method as:
public static void main(String[] args)
well you didn't print the value return from function :
in your main do this:
System.out.println(EvenOrOdd(5));

Return statement doesn't break out of block, even though condition is true

This is a simple program to check if a number if Fibonnacci. I have a mysterious bug: the "return true" statement isn't triggered. Instead, "hi" will be printed many times. Return should break out of the method, does anyone have insight as to why it's not? Thanks!
import java.util.*;
public class Solution {
public static boolean listFibs (long oldestFib, long oldFib, long input) {
long newFib = oldestFib + oldFib;
while (newFib < Math.pow(10,10)) {
if (newFib == input) {
System.out.println("hi");
return true;
}
listFibs(oldFib, newFib, input);
}
return false;
}
public static void main(String[] args) {
/*Scanner in = new Scanner(System.in);
int testCases = in.nextInt();
for (int i = 0; i < testCases; i++) {
int a = in.nextInt();
System.out.println("A= " + a);
System.out.println(listFibs(0, 1, a));
}*/
System.out.println(listFibs(0, 1, 5));
}
}
Due to the recursion there are many incarnations of listFibs. The return just leaves one of them.
In the example given, you get the following calls:
listFib(0,1,5)
listFib(1,1,5)
listFib(1,2,5)
listFib(2,3,5)
-> true
listFib(2,3,5) // called again due to the loop
-> true
listFib(2,3,5) // called again due to the loop
-> true
listFib(2,3,5) // called again due to the loop
-> true
listFib(2,3,5) // called again due to the loop
...
actually, if "hi" is printed many times, the return statement must be executed the same time. if you install a break point in that return statement, you will see.
your function is a recursion, and "listFibs" will be called many times.
Print values of all 3 variables in the method and you will know what's wrong. You are using recursion, see how many times it's being called.
Also, after call to listFib, execution will go to while loop again. You need to say return listFibs at least. Between your listFibs and while loop condition, nothing is changing. 2,3,5 are being found again and again.
see http://ideone.com/1d440f
You are one step short... The recursive call doesn't do anything with the results you get from listFibs, so the program sees something like this:
while (newFib < Math.pow(10,10)) {
if (newFib == input) {
System.out.println("hi");
return true;
}
true //or false
}
Try adding this extra little IF statement. Once a true result is found it will be passed back up the chain and out of the function.
while (newFib < Math.pow(10,10)) {
if (newFib == input) {
System.out.println("hi");
return true;
}
if listFibs(oldFib, newFib, input){
return true;
}
}

Java - How to identify whether a method executed completely or Returned

Is there a way to identify whether the following method executed completely or returned halfway through(i.e at line no 3)
static int a=0;
static void test(){
if(a>10){
return;
}
a++;
}
The method was invoked by another method.(a might have been changed by it)
I cannot change the method declaration. I am dealing with an object I created from a java file created by someone else. I am not allowed to change the original file
Your method does almost nothing and no there is no way in this example you gave to know if the method returned before complete execution but if you willing to change the function to a boolean type you can return true at complete execution and false at incomplete.
static boolean test()
{
if(a>10)
return false;
a++;
return true;
}
Run the code under debugger like jdb and set the breakpoint on the internal return statement. If the program stops at this breakpoint, this obviously means that it would return through that statement.
To make things more automated, you could try to launch the debugger and control the debugger from a Java program through Runtime. This would make the approach applicable for more use cases, while not for all.
You could use
void test(int a) {
if (a > 10) {
return;
}
a++;
System.out.println("test executed completely!");
}
Or if you want to use the information programmatically
private boolean executedCompletely;
void test(int a) {
executedCompletely = false;
if (a > 10) {
return;
}
a++;
executedCompletely = true;
}
When you use your test method, you can check whether it ran completely this way:
int initialA = a;
test();
int finalA = a;
if (finalA != initialA) {
//a has been changed, therefore the method ran completely
} else {
//a has not been changed, therefore it was not incremented, therefore the method did not run completely
}

Categories

Resources