Extremely weird behaviour of return statement : Java - java

OK I have a weird problem. The code is as follows :
The method name is returnMultiPartHeading
if (recursionCount > 6 || i == list.size() - 1)
return -1;
multiPartHeading = multiPartHeading + " " + list.get(i + 1).getText();
Token token = new Token();
token.setText(multiPartHeading);
if (isHeadingType(token)) {
System.out.println("found " + multiPartHeading);
System.out.println("returning ...");
System.out.println("I is " + (i + 1));
return (i + 1);
} else {
returnMultiPartHeading(list, i + 1, multiPartHeading,
++recursionCount);
}
System.out.println("returning -1");
return -1;
}
The output is for a sample run is :
found xyz
returning...
I is 2
returning -1
why is this happening?? the if (isHeadingType(token)) evaluates to true , prints the two messages and then it totally skips the return i+1 and goes to return -1 instead. In the place I called it, I get -1 as the returned value instead of getting 2. Why is this happening?? Never saw this behaviour.

It's because in your else block, you don't actually return the result of the recursive call. You just call the method, ignore its result, and then fall through to the section below (with the return -1).
You need to change your else block to
else {
return returnMultiPartHeading(list, i + 1, multiPartHeading,
++recursionCount);
}
(assuming that your method really is called returnMultiPartHeading, which somehow doesn't sound right)

Looks like two calls are performed, the first wrote
found xyz
returning...
I is 2
and the second
returning -1
as it is a recursive method I think thats the reason

The if block is the second recursive call, which returns to the first recursive call, which was probably called by the else block. In the else block you do not return the value. Hence it skips out and returns -1.

Related

How to change the return value of a method in Intellij?

How can I change the return value of a method in Intellij?
The method's value is not set to a variable so there is not work around it.
I think this is as close as you can get to storing the result of foo() inside your if condition:
int result;
if((result = foo()) % 2 == 0){
System.out.println(result + " is even.");
}else{
System.out.println(result + " is odd.");
}
You can't actually declare result inside the condition, you have to do that before.

Working of Return statement in a method in Java

I am trying to understand the working of return statement in JAVA.
My doubt is if inside a method with a Non void return type, I have a decision block which also has a return statement of its own, Still I have to return some value .
For understanding here is a sample code I have written :-
public int bunnyEars(int bunnies) {
//int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
return count1;
}
return count2 ;
}
In the mentioned code I just want to return the no. of bunnies which I am being able to do from inside the bunnyEars method count1. But still JAVA wont allow to have a non-void method without a return type which is totally understood and I have to add count2 return also. Now I am suspecting that I am having a conceptual understanding failure here. Kindly let me know if I am missing something? Kindly let me know If I am missing some more info here.
[Edited] Full code:
public class Test5 {
//public int ears=1;
public int count=0;
public int bunnyEars(int bunnies) {
//int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
return count;
}
return count ;
}
public static void main(String args[]){
Test5 test5= new Test5();
System.out.println(test5.bunnyEars(90));
}
}
Yes you need to return count2 which should be zero. Which means if there are no bunnies then there are no ears. So which returning you should be returning some value irrespective of the conditional block.
So in this case
return count1;
represents the number of ears if the bunnies are represent, while
return count2;
represents the number of ears when there are no bunnies, which should be 0.
I hope that gives you some clarification
I think your conceptual misunderstanding lies with understanding the flow of the program.
Supposed you were to use this method by calling:
bunnyEars(2)
Then, once you enter the method, the first thing the program does is check if 3 >= 1. Since this is true, you proceed into the code inside the {..} (called a 'block'). Inside this block, you increment count by 2. I am assuming count is defined elsewhere in the class, but suppose the current value for count is 10. Then, the new value of count will be 12.
After this, the program executes the line:
bunnyEars(bunnies - 1)
Which translates to:
bunnyEars(1)
Now, basically, you are calling the same method again, but passing in 1 instead of 2.
Once again, the program checks to see that 1 >= 1, which is true. So it goes into the
if-block which, again, increments count by 2. So now, count = 14. Then it calls the
same method again but this time passing in 0.
bunnyEars(0)
Since 0 >= 1 evaluates to false, you the program skips the if-block and continues
execution after the block. So know, you are in the method bunnyEars(), but you have
completely skipped over your "return" statement. But, alas, bunnyEars MUST return an int.
So this is why you must have a return after the block. In your case, bunnyEars(0) returns count2 and the program-execution returns to where you called bunnyEars(0).
Read up on recursive calls. The basic idea of a recursive method is that, inside the recursive method, you must have some case that terminates the recursion (otherwise you will loop forever).
For example, the following code will go on forever:
public int sum(int in)
{
return in + sum(in - 1);
}
This will keep going on forever, because sum(1) will call sum(0) which calls sum(-1).
So, I must have a condition that terminates the recursion:
public int sum(int in)
{
if(in == 0) return 0;
return in + sum(in - 1);
}
Now, I have a terminating-case. So if I call sum(1), it will call sum(0) which returns 0. So my result is 1 + 0 = 1.
Similarily,
sum(2) = 2 + sum(1) = 2 + 1 + sum(0) = 2 + 1 + 0
sum(3) = 3 + sum(2) = 3 + 2 + sum(1) = 3 + 2 + 1 + sum(0) = 3 + 2 + 1 + 0 = 6
Hope this helps!
So as I understand it, your question is why you still need to return count2 if you return count1. The answer is basically 'what happens if you don't enter the if block?'. In that case, without return count2, you wouldn't have a return value, which is what Java is complaining about. If you really don't want two return statements, you could probably do something like:
public int bunnyEars(int bunnies) {
int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
}
return count ;
}
On a side note, this and the code you posted in your question won't work for regression purposes, but the one in your comment does, and there it looks like you have a static variable for count, in which case you could set the return type to void and just print count.

JAVA - While loop exiting when it shouldn't be?

ive been trying to fix this problem for myself for about 2 hours. I'm guessing someone is going to instantly spot out my problem. So my problem is that a while loop(or .equals is giving an incorrect result). Here's the code:
Integer i = 0;
while(!type.equals(questionArray.get(i).questionType) && Questions.hasQuestionBeenUsed(i)) {
i++;
}
System.out.println(i + " type=" + type + " - questionType" + questionArray.get(i).questionType);
usedQuestionIndexes.add(i); //if question index has not been used - add it to used indexes
So the problem here is its exiting when the variable "type (string)" when it doesn't equal "questionArray.get(i).questionType (string)" which it shouldn't be. So lets say "type = 'hello'" and "questionArray.get(i).questionType = 'hi'" it is coming out of the loop?
The output from the code from the code above is this:
1 type=general - questionType=sport
So what is the problem here? Why is it saying the first condition is true when its not? the second condition is saying false(which is correct) heres the code for the method "hasQuestionBeenAsked":
public static Boolean hasQuestionBeenUsed(Integer questionIndex) {
for(Integer usedQuestionIndex : usedQuestionIndexes) {
if(questionIndex.equals(usedQuestionIndex)){
return true; //if index is found in usedQuestionIndexes array it will return that the index has been used
}
}
return false;
}
Thanks! If you need any extra info just tell me!
It's very simple - it's because you are negating the false by using the negation operator - (!). So even though you have false, you are ending up with true because (not) false = true. In your case, use
// Remove the negation - !
while(type.equals(questionArray.get(i).questionType) && Questions.hasQuestionBeenUsed(i)) {
i++;
}

If statement not properly working in java

I have a question about if statements and defining integers.
In this code:
if(matches!=null) {t =1;
for (String match : matches) {
if (t == 1 && "one".equals(match)) {
testSound.start();
t = 2;
System.out.println("the value of t is" + t);
} else if (t == 2 && "two".equals(match)) {
testSound.start();
t = 3;
System.out.println("the value of t is" + t);
}
}
If the first if statement executes and returns 2, and then match = "two", will the else if statement work? If not, how would I make it so that when I set t=2, it is actually t=2. Right now it's not working so let me know!
Everything works correctly: the t++ executes before System.out.println, so by the time the t is printed its value is already 2, not 1. If you need 1 printed, move t++ so that it comes after printing.
The second if statement is not executing after that because match is "one", not "two".
You can do System.out.println("the value of t is" + (t++));.
That way you will first print the value of t to the console than add 1 to its value.

Does "return" stop the execution of a method?

I have programmed a method in the following way:
if (something) {
return 1;
}
the rest of the code
It seems to me that the method returns 1 and then execute the rest of the code. Can it be the truth? Doesn't return stops the execution of the code. It it is not, how can I force a method to stop?
ADDED
Here is the code (as requested):
for (int i=availableTime; i>0; i=i-1) {
final int sec = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
String lbl = "<html>";
lbl += "</html>";
timeLeftLabel.setText(lbl);
}
});
try {Thread.sleep(1000);} catch (InterruptedException e) {}
parameterFromClientsListener = clientsListener.getValue(userName,parameterToGet);
if (!parameterFromClientsListener.equals("null")) {
output = parameterFromClientsListener;
game.log.fine(userName + " set (by button) " + parameterToGet + " to be equal to " + output + " . [IMPORTANT]");
return output;
}
}
game.log.fine("The partner selection phase is expired.");
// This code is executed if the Submit button was not pressed and the time run out.
if (parameterToGet.equals("partner")) {
tellMyChoice(parameterToGet, this.partnerFromForm, "timer of" + field);
output = this.partnerFromForm;
}
game.log.fine(parameterToGet + " was submitted by timer (not by OK button).");
} else {
output = parameterFromClientsListener;
}
game.log.fine(userName + " set (by timer)" + parameterToGet + " to be equal to " + output + " . [IMPORTANT]");
return output;
}
I run this code two times. In every case I generate a log-file. In both log files I see "set (by button)" statement (which is straight before the return). But the problem is that in the second log file I do see "timer of" statement. Which should not be reached if the "set (by button)" is reached. How can it be? I need to mention that "set (by button)" and "timer of" do not occur anywhere else in my code (they occur only once).
ADDED 3
As you can see from the code I do not have the finally statement.
This is not true, the return statement will stop any following code. (With the only exception being that the return statement is in a try{} block that has a finally{} block afterwards.
if(0==0){
return;
}
System.out.println("This will not print.");
return does end the execution of the method. There is one exception: the finally block. In the following case, 2 would be returned
public int foo() {
try {
return 1;
} finally {
return 2;
}
}
Return does indeed end the execution of a method. Check Your other assumptions. Maybe something in other parts of code isn't working as You are assuming.
Does return stops the execution of the code
well, almost.
Once a return is encountered, the method execution is stopped, and the control is passed to the calling method, after executing any finally clauses.
int add(int a, int b)
{
try{
if(a == 0)
{
return b;
}
if(b == 0)
{
return a;
}
return a+b;
}
finally
{
System.out.println("Finally");
}
}
In the above code, is the function is called as add(0, 1), "Finally" will still be printed.
How can I force a method to stop?
OR What are the other ways of exiting from a method?
Exceptions
You write
if (!parameterFromClientsListener.equals("null")) {
output = parameterFromClientsListener;
game.log.fine(userName + " set (by button) " + parameterToGet + " to be equal to " + output + " . [IMPORTANT]");
return output;
}
You are comparing the string (or whatever) with the string "null", and return if they are different. Do you really want to do this, and not parameterFromClientsListener != null?
(Though that should not be a big difference, as long as parameterFromClientsListener is neither null nor "null", and if it is null, your version would give a NullPointerException.)
Do you actually get the entry in your log file? If so, you should also get the return.
I wanted to understand how the observed behavior can be possible. In more details, I saw a "paradoxical" behavior. In my log files I saw output of the line which happens before the return as well as the output produced by the code after the return. So, I assumed that the return does not stop the execution of the program. As it has been correctly mentioned here by other "answerers" this assumption is wrong. The explanation of the behavior is trivial. My program run the shown code several times. The first time it reaches the return statement, the second time it passes it (because the return is in the if statement). So, it is why IO have the both statements in the log file.

Categories

Resources