I've seen answers using a for loop which I understood, however I came across this code recently and I have no idea how it works.
public class learn {
public static int factorial (int N){
if (N<=1 ) return 1; // won't this mean that "1" is returned at the end all the time?
else return (N*factorial (N-1)); /* since there's no variable storing the sum
I don't get how this is working out either,
won't it just be returned and lost?*/
}
public static void main(String[] args) {
System.out.println(factorial(4));
}
}
Coming from a python background, so maybe I am misunderstanding something about returns in java... [Edit] seems like return 1 is also written in Python, so it's probably not a language issue, I just don't get how recursive functions end (I get how the process goes - it's a function that calls itself).
Here's an illustration of how I interpret this code (wrongly):
factorial(4) is called
4 is more than 1, so the else statement will run -- 4*factorial(3)
factorial(3) is called - else statement runs again -- 3*factorial(2)
factorial(2) is called -- 2*factorial(1). At this point, we have 4*3*2*1 but the fact that the code only stops at the if (N<=1) return 1 line means that 1 is returned instead of the sum right? (I'm obviously wrong because the console printed the right number - 24)
won't this mean that "1" is returned at the end all the time?
No, it will only return 1 when N is less than 1. (according to your condition if (N<=1 ) return 1;)
For all other cases, it continues recursively.
since there's no variable storing the sum
I don't get how this is working out either,
won't it just be returned and lost?
When a method returns, it exits the current method and return to the point of invocation and continue from there. For simplicity, take this scenario: methodA calls methodB, and methodB calls methodC:
public void methodA(){
print("entering method A.."); //(1)methodA invoked..
methodB(); //(2)call methodB
print("exiting method A"); //(8)exit from methodB, continue from here
}
public void methodB(){
print("entering method B.."); //(3)mthodB invoked..
methodC(); //(4)call methodC
print("exiting method B"); //(7)exit from methodC, continue from here. exit methodB
}
public void methodC(){
print("entering method C.."); //(5)methodC invoked..
print("exiting method C"); //(6)exit methodC, continue from whoever called methodC
}
You will get the outpus as follows:
entering method A..
entering method B..
entering method C..
exiting method C
exiting method B
exiting method A
If you can understand the program flow of methodA B and C. Now try to understand a method calling "itself".
//Let say N is 3..
public static void main(String[] args){
factorial(3); //(9)
}
public static int factorial (int N) //(1)N:3, (3)N:2, (5)N:1
{
if (N<=1 )
return 1; //(6)Ret 1, return and continue from whoever called me
else
return (N*factorial (N-1)); //(2), (4), (7)Ret 2*1, (8)Ret 3*2*1
}
At (6), it exits the method by returning 1 and continue from the place which called this method. The place where it was called is at (7).
At (7), it exits the method by returning N*1 (which is 2*1 = 2) and continue from the place which called this method. The place where it was called is at (8).
At (8), it exits the method by returning N*2 (which is 3*2 = 6) and continue from the place which called this method. The place where it was called is at (9) which is the main method.
The if statement only returns 1 if the parameter N equals or is smaller than 1, otherwise the else clause will be executed. In the else clause, since it returns a product of parameter N and the returning value of factorial(N-1), Java needs to wait for factorial(N-1) to return a value in order to do the multiplication and return the value. There is no need to store the value of parameter N into a field since a parameter is also a variable, just its value is passed from the method's caller.
In your code, the factorial is invoked 4 times.
Related
I'm pretty confused about some java behavior, especially because my previous understanding of java was that it was strictly pass-by-value.
If I pass an object to a method, then null that object in the calling thread, I would expect the object would still exist and be able to be operated on in the method, but this is not the case.
Here is some sample code:
public class methodTest {
boolean bool;
boolean secondBool;
Test list;
public static void main(String[] args) {
new methodTest().run();
}
public void run() {
list = new Test();
new Thread(() -> {
func(list);
}).start();
list = null;
bool = true;
while (!secondBool) {
// block
}
System.gc();
}
public void func(Test big) {
while (!bool) {
// block
}
System.out.println(big);
secondBool = true;
}
class Test {
#Override
protected void finalize() throws Throwable {
System.out.println("I'm getting cleaned up!");
}
#Override
public String toString() {
return "Test!";
}
}
}
This code prints
null
I'm getting cleaned up!
when I would expect it to print:
Test!
I'm getting cleaned up!
I included the garbage collection call at the end and the finalize method in the class to ensure that the gc wasn't getting to the variable list before the function could print it, but the same effect occurs without it.
What is the explanation for this behavior?
EDIT:
Another example of this would be if you changed the list = null line in the run method to list = new Test(), then slightly modified the toString to count the number of Test instances. The program would print "Test2" instead of "Test1", because the value of the parameter in func was overridden in the calling thread, even though in my understanding of java's pass-by-value system, this should not happen.
It prints null because there is a race condition and the new thread loses most of the time.
The timing is like this:
the main thread (the one running methodTest.run()) creates a new Thread object and starts the new thread (meaning it creates a new linux/windows thread and notifies it that it can start running)
as the very next step it sets the instance variable list to null
in parallel to the step 2 above the second thread starts running and eventually reaches the lambda () -> { func(list); }
only when the second thread executes func(list); will it read the instance variable list
What is passed as parameter big into func therefore entirely depends on
how much time the main thread needs to execute list = null;
how much time the os needs to start executing the second thread and for the second thread to reach the point where it calls func(list);
From your observation the second thread needs more time to reach the point where func(list); is executed than the main thread needs to execute list = null;
If I remember Java correctly, it changes the value for user defined classes. So if you use primitive data types and already defined classes like int, string, etc then it wont cause you this problem. But here you are using your own class so its passed by reference for some reason.
I have a requirement where i need to call multiple methods in a sequential manner. But if any one of the method fails due to a validation, the program should not continue. I cannot use "Throw Exception because these are not actually exception rather than a condition that satisfies my requirement and after satisfying it, I don't want the program to continue.
Below is a piece of code for example and understanding. Even i use Return, it still continues to next method.
public void method1(){
System.out.println("Method 1");
return;
}
public void method2(){
System.out.println("Method 2");
return;
}
public void method3(int a) throws Exception{
System.out.println("Method 3");
if (a==3) FinalMethod();
return;
}
public void method4(){
System.out.println("Method 4");
return;
}
public void method5(){
System.out.println("Method 5");
return;
}
public void FinalMethod() {
System.out.println("This is the final method - end of the program");
return;
}
public void callMethod() throws Exception{
method1();
method2();
method3(3);
method4();
method5();
}
The method callMethod will be called from Main method. Please help me to learn this.
Edited: If The argument is 3 in method3, it should call Finalmethod and after that the program should end. I dont want it to go for method4 and method5.
Why not have the methods return a boolean to determine if the next method should run?
This is what's currently going on in in the stack when you call FinalMethod from method3:
main -> callMethod -> method3 -> FinalMethod
So when FinalMethod finishes, you go back to method3, and from there, go back to callMethod, and continue running to the end.
What I would do is make method3 return a boolean if you want to exit and call it with regard to this:
public boolean method3(int a) {
System.out.println("Method e");
return a==3;
}
...
//In callMethod
if (method3(3)) { //If we want to exit after running method3
FinalMethod();
return;
}
Though you may use System.exit(exitCode), this is not good practice, as it violates the program flow - that the program will only end at the end of the main function.
Though method3 is currently throwing an exception, you don't actually throw one in the method. However, exceptions should only be used for undefined behaviour (particularly relating to circumstances beyond your control, eg. external code). It is preferable to provide a user-friendly error and continue the program if possible, or exit gracefully if not.
Unrelated tips:
You do not have to call return at the end of a void function.
By default, you should make methods private, and only make them public when required
Calling return at the end of a method block is redundant in this scenario.
Assuming that you are looking to terminate the program on error, you can possibly use System.exit(-1) in your catch (if you follow this way), or in the if statement, if this is how you are checking for the error
Edit: I should also clarify that there is no specific meaning to using System.exit(-1) as opposed to using any System.exit(n) where n != 0, unless otherwise specified in your own documentation
I have the following Java program:
public class A extends Thread {
int count;
#Override
public void run() {
while (true)
count++;
}
public static void main(String...strings){
A obj = new A();
obj.start();
System.out.println("The value of count is " + obj.count);
}
}
When running this program the output is: The value of count is 0 (and the program stays running). As far as my understanding with thread it should run in an infinite loop and never print 0. Could anyone help me understanding the nature of this program.
The thread starts at about the same time as the System.out.println runs, and since the thread is background, the println does not wait for it to run, and so you are seeing the initial value of count.
Also as an aside, the count variable should be declared volatile to ensure that the main thread sees changes to the variable made in the loop thread.
The "thread" isn't doing the print, your main is. What were you expecting to happen?
You should also use some kind of protection so both threads can safely access the variable.
Wouldn't the System.out call only run once?
I would put the System.out.println call inside the while loop.
Its probably better to use a getter/setter method for count and make sure only one or the other can access the variable at any given time.
I'm encountering the following error:
Exception in thread "main" java.lang.StackOverflowError
at Account.draw(Account.java:47)
This is the relevant section of code:
public double draw(double c) {
if (c > 0) {
return c;
} else if (c < 0 && c > AccBalance) {
AccBalance=-c;
return AccBalance;
}
return draw(c);
}
How can I fix this?
In your code, if c == 0, or c <= AccBalance, you keep on recursing the method with the same value of c. So, it will go into an infinite recursion, thus filling up the stack.
For each method invocation, a stack frame is allocated from the stack. Thus your code will end up allocating complete stack memory.
So, for e.g, if you call this method first time with c = 0, this is how the stack grows:
draw(0)
draw(0)
draw(0)
draw(0)
.. so on
You keep on passing 0 as argument, which doesn't satisfy any of your base cases.
As to how to solve this, we don't really have enough context to find out what should go in place of return draw(c);. But certainly that shouldn't be there. Perhaps return draw(++c);?? But we can only guess.
See also:
Recursion: Behind the Scenes
You're continually calling the draw() method. So you call the draw() method, then it calls the draw() method, then it calls the draw() method, then it calls the draw() method, et cetera, until you have no more memory left.
Check your return statement at the end. What do you want to return in that case? Right now it just keeps calling draw() again, which is probably not what you want.
You have an infinite recursion. StackOverflowError means your call stack got too deep - too many nested functions called without completing any of them - which recursion tends to do.
I'm preparing for an exam and after going over some sample exercises (which have the correct answers included), I simply cannot make any sense out of them.
The question
(Multiple Choice): What are the some of the possible outcomes for the program below?
A)
Value is 1.
Value is 1.
Final value is 1.
B)
Value is 1.
Value is 1.
Final value is 2.
C)
Value is 1.
Final value is 1.
Value is 2.
D)
Value is 1.
Final value is 2.
Value is 2.
The Program
public class Thread2 extends Thread {
static int value = 0;
static Object mySyncObject = new Object();
void increment() {
int tmp = value + 1;
value = tmp;
}
public void run() {
synchronized(mySyncObject) {
increment();
System.out.print("Value is " + value);
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread2();
Thread t2 = new Thread2();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.print("Final value is " + value);
}
}
The correct answers are: A), C) and D).
For case A) I don't understand how it's possible that both threads (after incrementing a seemingly static variable from within a synchronized block(!)) end up being set to 1 and the final value is thus 1 as well...?
Case C and D are equally confusing to me because I really don't understand how it's possible that main() finishes before both of the required threads (t1 and t2) do. I mean, their join() methods have been called from within the main function, so to my understanding the main function should be required to wait until both t1 and t2 are done with their run() method (and thus have their values printed)...??
It'd be awesome if someone could guide me through this.
Thanks in advance, much appreciated!
wasabi
There is something wrong with the answers or the question.
Your understanding of join() is correct. The "Final value is" message cannot be printed until both threads have completed. The calls to join() ensures this.
Furthermore, the increment() method is only called from within a synchronized block keyed on a static field. So there's no way this method could be called simultaneously by two threads. The "Value is" output is also within the same synchronized block. So there's no access to the value property from anywhere except within the synchronized block. Therefore, these operations are thread-safe.
The only possible output from this program is "Value is 1. Value is 2. Final value is 2." (In reality, there are no periods or spaces between the outputs - I'm just matching the format of the answers.)
I cannot explain why this matches none of the answers except that whoever wrote the question messed something up.
First i'd like to agree with rlibby. His answer can be proven by writing the program an present the output to the teacher.
If we omit that look at this:
its guaranteed to have two prints of 'Value is...'
it's not possible to print 'Value is 1' twice, since the increment is synchronized by a static object (this eliminates A and B)
the order of the print statements can not be forecasted
but: if we read a 'Final value is x' there must be a 'Value is X' too, no matter if before or after but it must exist