Here is the content of a main function which blocks when the print line is commented, yet it executes as expected when the print line is uncommented.
Why would a single print line change the behavior of the whole while loop? (Between not executing at all, and completing successfully.) This is repeatable, I can comment and uncomment the line any number of times and I get the same result: it only works when the print is uncommented.
Any rational explanation to this strange effect of the print call?
MainGUI.main(args);
DeviceManager device = DeviceManager.getInstance();
MainGUI gui = null;
while(true){
if(device.getGui() != null){
gui = laser.getGui();
if(gui.isLoaded()){
gui.getMainView().getFrame().setLocation(0, 0);
break;
}
}
// System.out.print("");
}
The println is likely slowing execution of the tight loop enough to yield the processor to other threads that are necessary for your code to complete. I'll bet a Thread.sleep(5); will do a similar thing.
Related
I will show you my submitted assignment's answer to give the idea of it
void chkbnch()
{
System.out.println("\n The students under notice period are =>\n\n");
for(int i=0;i<25;i++)
**ol:{**
int cnm=0;
int cnm2=0;
for(int j=0;j<7;j++)
{
if(mrks[i][j]>=50)
{
cnm++;
}
if(cnm==3)
{
//i++;
**break ol;**
}
if(mrks[i][j]<50)
{
cnm2++;
}
}
if(cnm2>=3||cnm<3)
{
System.out.println("\n Student id =>"+(i+1));
}
}
}
Here I am using break when I don't want the loop to increment and just repeat the loop statement. I know this can be done by also decrementing the loop control but that's not what my question is.
All I want to ask that is this behaviour defined in java or is it just a chance that this is its outcome.
This use of the break statement is perfectly legal, although it is unusual, and it doesn't do what you say you want.
JLS §14.15 says:
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a switch, while, do, or for statement.
The "labeled statement" in your example is the {..} block statement, which is the statement executed by the for loop. When you execute the break, that block statement completes, which returns control to the for loop, which continues by executing the increment i++, testing the condition i<25 and then getting on with the loop.
It has the same behavior as labeling the outer loop directly, and then using continue ol;.
The loop counter will still be incremented. If you want to prevent that, either counteract it with a manual i--; or move i++; out of the for loop header and to the end of the loop body.
Seems like you want the continue keyword instead of break. continue breaks the current iteration of the loop and execution jumps back to the evaluation stage where the looping continues if the evaluation passes. break breaks the current iteration of the loop and execution jumps to the first line after the end-of-loop closing brace.
EDIT: If you need the loop increment control to "not increment" when you continue looping, so that, for example, the same object is pulled from the list being looped over after continuing, then you need to roll your own solution.
So I have this code and it is inside a while(MainMenu) and what i want to learn is how to restart my code.. Sometimes using MainMenu=false; and then MainMenu=true; works but sometimes it doesnt causing me to use return to crash the program because the user can cheat...
if(CitizenLoveNum<=20){
JOptionPane.showMessageDialog(null, "Your citizen are protesting against you! You need to stop them now before something really bad happens", "Citizens on Strike!", JOptionPane.WARNING_MESSAGE);
String Strike=JOptionPane.showInputDialog("Choose 1 of the options below! \n 1.Pay Them (-1000$) \n 2.Send Army (With this move you can lose from 0 to 5 men!)", "Citizens on Strike!");
if(Strike.equals("1")){
if(MoneyCount<=0){
JOptionPane.showMessageDialog(null, "Out Of Money! Try again later..", "No Money Left", JOptionPane.WARNING_MESSAGE);
return;
}
JOptionPane.showMessageDialog(null,"The Citizen's are calm once more. But try buying them recources so that won't happen again!", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
MoneyCount-=1000;
MainMenu=false;
MainMenu=true;
}else{
Random Army= new Random();
int ArmyNum = Army.nextInt(5 - 0) + 0;
JOptionPane.showMessageDialog(null,"You have sent the army. You lost "+ArmyNum+" Soldiers.", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
SoldierCount1-=ArmyNum;
MainMenu=false;
MainMenu=true;
}
}
It works where i putted the MainMenu=false; MainMenu=true; but it doesnt where i used return; i had to put return; because MainMenu=false; MainMenu=true; was not working. Thank you for your time :)
Edit: it usually does not work when I use an if inside an if... hope that helps
From what I can interpret, you probably have some code like this:
while(true) {
// A: Do stuff here
while(MainMenu) {
// B: Stuff before your posted code
if(CitizenLoveNum<=20){
// C: Your posted code
}
}
// D: Do other stuff here
}
If you want to go to B, use continue;.
If you want to go to D, use break;.
If you need to go to A without touching D, then enclose D in an if statement.
If your program is ending when you use continue, you probably are missing the while(true) at the top. This part is necessary to keep your code running unconditionally, forever. Otherwise, upon exiting while (MainMenu), your program will run to completion.
Also, I would like to add that
MainMenu = false;
MainMenu = true;
Is equivalent to
MainMenu = true;
Your code executes sequentially. Once you are inside the while loop, MainMenu is not checked again until you encounter a continue or all the code inside the loop finishes executing.
If you want to return to the top of the while body, you can use the keyword
continue;
Changing the MainMenu value in the while body will not cause any action becuase it gets checked before every new loop, the continue keyword will be applied immediately.
This:
MainMenu=false;
MainMenu=true;
Is the same as this:
MainMenu=true;
You're assigning a value that will be checked when it gets back to the start of the loop. If the value is true at that point, it will continue. So if you want to continue looping, set it to true. If you want to stop, just set it to false. Do one or the other, not both. Note that MainMenu=false will continue executing the current loop, and (unless it later gets set to true) will stop it from looping again.
What the return statement does is exits the function that your while loop is enclosed in entirely. If you had cleanup code after the end of your loop, you wouldn't want to return, as that would skip it.
If you want to execute more code after the loop (not exit the function yet), but you want to immediately exit the loop without finishing the current iteration, you can use the break statement.
If you want to return to the start of your loop immediately (from anywhere in the loop) and continue executing it, use the continue statement. Whether the loop executes again will depend on the value of MainMenu.
I'm learning recursion and am having problems writing a 'simple' program. Help would be appreciated. Thanks!The code compiles with no syntax erros but i still cant use it to serve its purpose.
my updated code:
import java.io.*;
import java.util.*;
class recursion1
{
static Scanner inFile = null;
public static void main(String[] args) throws IOException
{
try
{
inFile = new Scanner(new File(args[0]));
}
catch (IOException e)
{
System.out.println("File may not exist");
}
reverse(inFile);
inFile.close();
}
public static void reverse(File inFile) throws IOException
{
String line = inFile.nextLine();
if (inFile.hasNextLine())
{
reverse(inFile);
}
System.out.println(line);
}
}
I'm confused as to the purpose of the counter. You decrement it, but you never evaluate it for any sort of logical comparison. I don't think it is unneccessary, you just need to utilize it in a comparison that is used to break the recursive loop. Recursion requires a part that makes a call to the recursive function, and another part that breaks the cycle and begins the process of backing out of the recursive calls.
Here is how to write a reversing program in general. I'm not giving you Java, I'm giving you "pseudocode".
function print_reverse(file)
local_variable line
line = read_from(file)
if (we are not at end of file)
print_reverse(file)
print line
Because line is a local variable, you get a new instance of it on each call to print_reverse(). When you read in the whole file, and you want to print the lines in reverse, the lines need to be stored somewhere. In this recursive function, the lines are stored one at a time, one in each call to print_reverse().
I like to think of recursive functions as "winding" further and further until they hit a limit, then "unwinding" as they come back out. The limit is called the "basis case". With any recursive function you need to have a clear idea of what your basis case is. For print_reverse(), the basis case is hitting the end of file on the input file.
After print_reverse() hits its basis case, it stops calling itself recursively; it prints a line and then unwinds. As each recursive call ends, it returns to the previous recursive call, which then in turn prints its line and unwinds again. This continues until the first call prints its line and terminates, at which point the recursion is finished and all lines have been printed.
So, to summarize: when "winding" we read a line and save it, the basis case is end of input, and when "unwinding" we print a saved line. Since unwinding occurs in the exact opposite order of winding, the lines print in reversed order.
If the input file is very large, this recursive solution may use up all the available stack space, in which case the program will crash. If you wanted to write a file-reversing program that could handle input files of any size, recursion is not going to work. However, look at how clean and simple this program is. Some problems are easier to code and understand if you use a recursive solution.
Reversing a file is pretty easy to do iteratively; just use a loop to read each line from the file and keep appending lines to some sort of list, then loop over the list in reverse printing lines. But other programs are elegantly simple when you write them recursively, and much harder if you don't. For example, the "Towers of Hanoi" puzzle has a very clean recursive solution.
http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/13/hanoi.html
Is there a way to pause a for loop in java? So is there a way to only go forward one iteration when prompted? I read this http://answers.yahoo.com/question/index?qid=20100212201605AAazS73 and the solution seems like it could have some problems mostly because I don't fully understand the order the for loop checks its header. The only method I could think of that could accomplish something similar is the following
do {
if (FLAG) {
//Do procedure
i++;
FLAG = false;
}
} while ( i < 6);
When the flag is true the procedure is done and the counter moves forward one. I don't like this, though, because it will keep looping as long as the counter is below 6, if I am not mistaken. Any ideas?
-Sorry for the lack of clarity. The FLAG in my case would be a static boolean that could be called from another class. The procedure I allude to is dependent on i.
When iterating through a for loop, for example, the one below, it does the following
for (int i = 0; i < 6; i++) {
// Do stuff
}
It declares the variable i and assigns a value of 0.
It checks the conditional i < 6. If true, then proceed to step 3. Otherwise go to step 6.
Goes through the body of the loop.
Increment the variable i due to the i++ in the for loop header.
Go to step 2.
The loop ends.
As for your objective, I'm not sure what your objective is. Are you looking to pause using a blocking method call? If so, then something like this would work:
for (int i = 0; i < 6; i++) {
System.in.readLine();
}
Alternatively, you could use some sort of flag that polls to check whether the loop should proceed, such as:
for (int i = 0; i < 6; i++) {
while (paused) {
// An infinite loop that keeps on going until the pause flag is set to false
}
}
Hope this helped.
It's not clear what sort of "prompt" you mean. You could certainly do something like:
for (int i = 0; i < 6; i++) {
System.out.println("Press return to continue...");
System.in.readLine();
// Do the body of the loop
}
That's appropriate for a console app, but obviously not for (say) a Swing app. It also doesn't address the FLAG part of your sample code, because it's not clear what that's meant to mean. Are you trying to prompt the user for more information, or just confirmation to continue? If you could clarify what you're trying to achieve, that would really help.
For the sake of testability, if this is for non-throwaway code you may want to extract the idea of a user prompt, so you can test with an implementation which doesn't actually prompt the user, but just records that it would have done so.
This would involve blocking the Thread that the for loop occupies.
You can do this simply, but not very well, with this:
for(something)
while(!FLAG)
//Do procedure
Another way would be to have another Thread going on, and have the main thread wait for that other thread.
Here's some more information: How to make a Java thread wait for another thread's output?
Your goal is somewhat unclear. I think you want your program to keep running until you get six of a certain input and if so, that approach will work, though of course you'll need to get input from the user to move the loop forward.
If your concern is that the while loop would use a lot of system resources, that will not be a problem.
Well, you could use Thread.Sleep(); to pause for a little bit between flag checks, but what you are really looking for is a function that blocks while waiting for input, System.in.readline(); blocks if I recall correctly ;) Like so:
int i = 0
do
{
if(FLAG)
{
//Do stuff
i++;
//Clear Flag
}
Thread.Sleep(50); //Sleep for 50 ms
} while (i < 6);
or like so:
for(int i = 0; i < 6; i++) //Execute readline 6 times.
{
System.in.readLine();
}
Others have covered how to use System.in.readLine() to have the program explicitly require action from the user.
If what you need is not to have the program wait for the user, but allow you - the programmer - to slow the program down, in order to be able to find and fix a bug, you might want to consider using a debugger as this is exactly what it is designed for.
Any modern Java IDE has a debugger. The keys chosen to use it, just varies.
If you are using Eclipse, you are using either F11 or Ctrl-F11 (assuming Windows) to run your program. The difference is that F11 starts your program inside a debugger and Ctrl-F11 doesn't.
Put the cursor at the first line inside the for-loop, and choose Run->Toggle Breakpoint. A blue bullet will show to the left of the line. This indicates that the breakpoint is active - the debugger will now stop your program every time it reaches that line.
Now run your program in the debugger with F11. The program stops at the line, and you can investigate your variables in the Variables pane as needed, and continue execution with F8 whenever you are ready.
I have a question about the order of the execution of statements in a catch block in Java.
when I run the following class Test1 (see below), I expect to have as output first Hi!, then the result of the e.printStackTrace(); statement, and then Bye!. However, I never get this order. Please, look at the outputs, which I have pasted below.
public class Test1 {
public static void calculate() {
try {
int h = 5/0;
} catch (ArithmeticException e) {
System.out.println("Hi!");
e.printStackTrace();
}
System.out.println("Bye!");
}
public static void main(String[] args) {
calculate();
}
}
Output1:
Hi!
Bye!
java.lang.ArithmeticException: / by zero
at Test1.calculate(Test1.java:6)
at Test1.main(Test1.java:15)
Output2:
java.lang.ArithmeticException: / by zero
at Test1.calculate(Test1.java:6)
at Test1.main(Test1.java:15)
Hi!
Bye!
I have two questions:
1.) The more important question: Why I always have Hi! and Bye! printed always one after the other, even though mye.printStackTrace() in the code is between them?
2.) Why sometimes I have the output of the statement e.printStackTrace() before Hi!, and sometimes after Bye! ? I have run the program many times and I cannot understand under what circumstances I get one or the other print.
Thank you.
I am using Java 6, and Eclipse (Ganymed).
Exception.printStackTrace() prints to System.err whereas "Hi!" and "Bye!" are on System.out. If you run your program on a regular console, they eventually end up on the screen, but the order may be out. If you are running the program through an IDE (e.g. NetBeans), the streams will probably be color-coded so you can easily distinguish them.
You print "Hi!" and "Bye!" to System.out (i.e. stdout), while the stack trace is printed to System.err (i.e. stderr). The order in which they are printed is determined by when the two buffers are flushed.
It could be a timing issue. Println writes to standard out, while printStackTrace might be hooked up to standard error. Then it's just a matter of which buffer gets flushed first.
A1 - e.printStackTrace() prints to System.err and not System.out, so different streams, different print order.
try adding System.out.flush() after every print (printStackTrace included).