I have a for loop that asks the user to input a number and then does something with it 10 times
I want a check built in that, if the user enters a non accepted input, the loop should restart its current iteration
For example if the user enters something wrong in round 3, round 3 should be restarted.
How do i do that? is there something like a REDO statement in java?
something like this ?
for(int i=0; i<10; i++){
if(input wrong){
i=i-1;
}
}
You have a couple of choices here.
Continue
The continue statement in Java tells a loop to go back to its starting point. If you're using a for loop, however, this will continue on to the next iteration which is probably not what you want, so this works better with a while loop implementation:
int successfulTries = 0;
while(successfulTries < 10)
{
String s = getUserInput();
if(isInvalid(s))
continue;
successfulTries++;
}
Decrement
This approach seems ugly to me, but if you want to accomplish your task using a for loop, you can instead just decrement the counter in your for loop (essentially, 'redo') when you detect bad input.
for(int i = 0; i < 10; i++)
{
String s = getUserInput();
if(isInvalid(s))
{
i--;
continue;
}
}
I recommend you use a while loop.
Prefer avoiding to reassign the i variable, this may lead to confusion.
for(int i=0; i<10; i++){
String command = null;
do{
command = takeCommandFromInput();
} while(isNotValid(command));
process(command);
}
Related
I've been trying to get this to work for a while. I'm putting in three parallel empty arrays and it errors out saying that there is no line found. It ONLY works when I change the while statement to the number of elements. I am trying to make arrays that are the size of 15, but only fill the first ten array portions.
Sorry if it sounds complicated, but basically I'm trying to say that the size of the array is 15, I only have 10 things to enter in the array, and the rest of them should be blank.
while (text.hasNext() && c < nameArray.length) {
nameArray[count] = text.nextLine();
intArray[count] = text.nextDouble();
doubleArray[count] = text.nextInt();
text.nextLine();
c++;
}
This does not work.
while (text.hasNext() && c < 9) {
nameArray[count] = text.nextLine();
intArray[count] = text.nextDouble();
doubleArray[count] = text.nextInt();
text.nextLine();
c++;
}
This does.
Your read the file TWICE within a single loop. Remove the 2nd read:
fileText.nextLine();
Of course it doesn't work. If you need to cycle to the max between fileText length and gameArray length, you should use or instead of and and use an if in the loop.
Try something like this:
while (fileText.hasNext() || count < gameArray.length) {
if (!fileText.hasNext()) {
gameArray[count] = "";
priceArray[count] = 0;
stockArray[count] = 0;
} else {
gameArray[count] = fileText.nextLine();
priceArray[count] = fileText.nextDouble();
stockArray[count] = fileText.nextInt();
fileText.nextLine();
}
count++;
}
Your issue is not with the length of the array but with fileTest.nextLine(). After a certain point there is no nextLine() available. It works for the 1st 9 times but I guess all the lines are exhausted before you reach array.length. I would suggest just one condition in your while loop:
while(fileText.hasNext()) {
}
This way you would fill in only the amount actually present.
Add another check with the second fileText.nextLine() to ensure that there is a line to read.
while (fileText.hasNext() && count < gameArray.length) {
gameArray[count] = fileText.nextLine();
priceArray[count] = fileText.nextDouble();
stockArray[count] = fileText.nextInt();
if ( fileText.hasNext() )
fileText.nextLine();
count++;
}
In the first version of your code, your try to read input 15 times, but it is entered only 10 times. So the scanner tries to read a new line but it doesn't exist.
Is there ever a situation where you must use a do while loop? Is it an accepted practice? It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
int i = 3;
while ( i > 0 ) { // runs 3 times
i--;
}
vs
int j = 3;
do {
j --;
} while ( j > 0 ); // runs 3 times
The same?
EDIT: I have seen the java doc, but
the example in the java docs doesn't look like it requires that the particular routine inside of the do while loop must be run in the do while loop instead of inside of a regular while loop!
Is there ever a situation where you must use a do while loop?
No: every do-while loop can be written as a while-loop by running the body once before the loop begins. However, there are certainly cases where it makes more sense to use the do-while construct (i.e. if you always want the loop to iterate at least once), which is why it exists in the first place.
Is it an accepted practice?
If you use it appropriately, then yes absolutely.
It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
That's right. You can read more about do-while in its tutorial.
This example maybe help you be clearer:
int i = 3;
System.out.print("while: ");
while (--i > 0){
System.out.print("x");
}
System.out.print("\ndo-while: ");
int j = 3;
do
{
System.out.print("x");
}while (--j > 0);
This prints
while: xx
do-while: xxx
A real time example.
There is a contest with 5 level.
In each level if you score 100 you can proceed to next level.
Less code for do while, but not for while.
boolean playContest()
{//do while
int level = 1;
int score;
do
{
score = 0;
score = play();
}while(score>99 && level++<6)
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
boolean playContest()
{//while
int level = 1;
int score;
while(level <6)
{
score = 0;
score = play();
if(score < 100)
break;
level++;
}
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
basic difference between while and do-while is do while will be executed at least once.
when do-while is best option?
in case when you want to execute some actions till you meet condition, of course you could achieve same thing by using while but early termination of loop with break, is nasty and ugly solution
When you want to execute the statement inside do for at least once, then you can go for it.
Directly from Docs
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once,
do {
statement(s)
} while (expression);
No, there is no time a do-while loops is the only option, it is used for convenience when you do not want to repeat code.
i have recrusive function which works fine. The problem is it gives stackoverflow error when the number of lines are huge. I want to put it in iterative, probably using a for loop. Need some help in doing it.
private TreeSet validate(int curLine, TreeSet errorSet) {
int increment = 0;
int nextLine = 0;
if (curLine == lines.length || errorSet.size() != 0) {
return errorSet;
} else {
String line = lines[curLine];
//validation starts. After validation, line is incremented as per the requirements
increment = 1 //As per requirement. Depends on validation results of the line
if (increment > 0) {
try{
Thread.currentThread().sleep(100);
}catch(Exception ex){
System.out.println(ex);
}
nextLine = (curLine + increment);
validate(nextLine, errorSet);
}
}
return errorSet;
}
Poster's description of the method:
The method does validates textlines, these lines has instructions of how much line has to be skipped, if the line is valid. So, if the line is valid that many of lines will be skipped using the increment. if the line is not valid increment will be 0.
I'm not sure why this was ever recursive in the first place. This is perfectly suited for the use of a FOR loop. use something like so:
private TreeSet validate(int curLine, TreeSet errorSet) {
int increment = 0;
if (errorSet.size() != 0)
return errorSet;
for (int curLine = 0; curLine < lines.Length; curLine += increment)
{
// put your processing logic in here
// set the proper increment here.
}
}
If the increment is always going to be 1, then you can just use curr++ instead of curLine += increment
for(String line : lines) {
// validate line here
if(!errorSet.isEmpty()) {
break;
}
}
The solution for your problem could be simple for loop or while, with logical expression for stop condition. Typically we use for loop when we have to pass through all elements of Iterable or array. In case when we are not aware how many loops we are going to do we use a while loop. Advantage of for loop over while, is that we for free have localized variables so we ca not use them out side of the loop, therefore we reduce possibility to have some bug.
You problem is that you have to break the program on two conditions:
When errorSet is not empty.
When the array of lines have no longer items.
As contradiction, we can say that your program should continue:
Until errorSet is empty,
and until line number is smaller than array size where they are stored.
This provide us to simply expression
errorSet.isEmpty()
lineNumber < lines.length()
We can combine them using logical operator && and use as a stop rule in for loop.
for(int lineNumber= 0; errorSet.isEmpty() && lineNumber< lines.length(); lineNumber++) {
//code to operate
}
Note:
Typically for logical expression is used operator &&, that assure that every part of the logical expression is evaluated. An alternative for this is &, that in case of false do not operate longer and return false. We could be tempted to use this operator for this expression but i would be bad idea. Because when we would traversed all lines without error code will generate IndexOutOfBoundException, if we switch the places then we would not have any optimization as first expression would be evaluated same number of times.
I want to have a for statement that repeats until a given int reaches a certain value.
For example...
for (int variable = 0; variable < other_variable; variable++) {
The problem with this is that the for statement will never end. It will continue to repeat endlessly. What have I done wrong?
This is my code...
boolean itemexist_check = false;
do {
int i2 = m_area.m_items.size();
for (int i = 0; i < i2; i++) {
String s2 = m_area.m_items.get(i).returnName();
System.out.println("Checking...");
if (s2.contains(s)) {
System.out.println("You take the " + s2 + ".");
itemexist_check = true;
player.addItem(m_area.m_items.get(i));
m_area.m_items.remove(i);
}
else {
//do nothing, repeat loop
}
}
}
while (itemexist_check == false);
In this code, m_area.m_items.size() would return 1, so i2 would be 1.
There are several possibilities:
you change variable inside the body of the loop;
you change other_variable inside the body of the loop;
other_variable is set to a large value, in which case the loop might take a long time to terminate;
your code never completes a certain iteration of the loop, for example:
it's getting stuck inside a nested loop as suggested by #Eng.Fouad in the comments, or
it's waiting for a lock, or
it's blocking inside an I/O call that never completes (or takes a long time to complete) etc.
Without knowing the typical value of other_variable and seeing the body of the loop it's anyone's guess.
On a side note,
String s2 = m_area.m_items.get(i).returnName();
is going to cause an exception if invoked in a subsequent or later repetition after
m_area.m_items.remove(i);
is invoked, because every time m_area.m_items.remove(i) is invoked, the list/array loses an item and its size reduces, which is never reflected in the iteration boundary check.
Surely it is the do/while loop that isn't terminating? That for loop cannot possibly run forever.
You should try a
do {
}while(condition is true)
loop. However that said, you have to implement checks assuming that there will be runaway data or conditions resulting in an infinite loop. Just my 2 cents
I saw this keyword for the first time and I was wondering if someone could explain to me what it does.
What is the continue keyword?
How does it work?
When is it used?
continue is kind of like goto. Are you familiar with break? It's easier to think about them in contrast:
break terminates the loop (jumps to the code below it).
continue terminates the rest of the processing of the code within the loop for the current iteration, but continues the loop.
A continue statement without a label will re-execute from the condition the innermost while or do loop, and from the update expression of the innermost for loop. It is often used to early-terminate a loop's processing and thereby avoid deeply-nested if statements. In the following example continue will get the next line, without processing the following statement in the loop.
while (getNext(line)) {
if (line.isEmpty() || line.isComment())
continue;
// More code here
}
With a label, continue will re-execute from the loop with the corresponding label, rather than the innermost loop. This can be used to escape deeply-nested loops, or simply for clarity.
Sometimes continue is also used as a placeholder in order to make an empty loop body more clear.
for (count = 0; foo.moreData(); count++)
continue;
The same statement without a label also exists in C and C++. The equivalent in Perl is next.
This type of control flow is not recommended, but if you so choose you can also use continue to simulate a limited form of goto. In the following example the continue will re-execute the empty for (;;) loop.
aLoopName: for (;;) {
// ...
while (someCondition)
// ...
if (otherCondition)
continue aLoopName;
Let's see an example:
int sum = 0;
for(int i = 1; i <= 100 ; i++){
if(i % 2 == 0)
continue;
sum += i;
}
This would get the sum of only odd numbers from 1 to 100.
If you think of the body of a loop as a subroutine, continue is sort of like return. The same keyword exists in C, and serves the same purpose. Here's a contrived example:
for(int i=0; i < 10; ++i) {
if (i % 2 == 0) {
continue;
}
System.out.println(i);
}
This will print out only the odd numbers.
Generally, I see continue (and break) as a warning that the code might use some refactoring, especially if the while or for loop declaration isn't immediately in sight. The same is true for return in the middle of a method, but for a slightly different reason.
As others have already said, continue moves along to the next iteration of the loop, while break moves out of the enclosing loop.
These can be maintenance timebombs because there is no immediate link between the continue/break and the loop it is continuing/breaking other than context; add an inner loop or move the "guts" of the loop into a separate method and you have a hidden effect of the continue/break failing.
IMHO, it's best to use them as a measure of last resort, and then to make sure their use is grouped together tightly at the start or end of the loop so that the next developer can see the "bounds" of the loop in one screen.
continue, break, and return (other than the One True Return at the end of your method) all fall into the general category of "hidden GOTOs". They place loop and function control in unexpected places, which then eventually causes bugs.
"continue" in Java means go to end of the current loop,
means: if the compiler sees continue in a loop it will go to the next iteration
Example: This is a code to print the odd numbers from 1 to 10
the compiler will ignore the print code whenever it sees continue moving into the next iteration
for (int i = 0; i < 10; i++) {
if (i%2 == 0) continue;
System.out.println(i+"");
}
As already mentioned continue will skip processing the code below it and until the end of the loop. Then, you are moved to the loop's condition and run the next iteration if this condition still holds (or if there is a flag, to the denoted loop's condition).
It must be highlighted that in the case of do - while you are moved to the condition at the bottom after a continue, not at the beginning of the loop.
This is why a lot of people fail to correctly answer what the following code will generate.
Random r = new Random();
Set<Integer> aSet= new HashSet<Integer>();
int anInt;
do {
anInt = r.nextInt(10);
if (anInt % 2 == 0)
continue;
System.out.println(anInt);
} while (aSet.add(anInt));
System.out.println(aSet);
*If your answer is that aSet will contain odd numbers only 100%... you are wrong!
Continue is a keyword in Java & it is used to skip the current iteration.
Suppose you want to print all odd numbers from 1 to 100
public class Main {
public static void main(String args[]) {
//Program to print all odd numbers from 1 to 100
for(int i=1 ; i<=100 ; i++) {
if(i % 2 == 0) {
continue;
}
System.out.println(i);
}
}
}
continue statement in the above program simply skips the iteration when i is even and prints the value of i when it is odd.
Continue statement simply takes you out of the loop without executing the remaining statements inside the loop and triggers the next iteration.
Consider an If Else condition. A continue statement executes what is there in a condition and gets out of the condition i.e. jumps to next iteration or condition. But a Break leaves the loop.
Consider the following Program. '
public class ContinueBreak {
public static void main(String[] args) {
String[] table={"aa","bb","cc","dd"};
for(String ss:table){
if("bb".equals(ss)){
continue;
}
System.out.println(ss);
if("cc".equals(ss)){
break;
}
}
System.out.println("Out of the loop.");
}
}
It will print: aa cc Out of the loop.
If you use break in place of continue(After if.), it will just print aa and out of the loop.
If the condition "bb" equals ss is satisfied:
For Continue: It goes to next iteration i.e. "cc".equals(ss).
For Break: It comes out of the loop and prints "Out of the loop. "
The continue statement is used in loop control structure when you need to jump to the next iteration of the loop immediately.
It can be used with for loop or while loop.
The Java continue statement is used to continue the loop. It continues the current flow of the program and skips the remaining code at the specified condition.
In case of an inner loop, it continues the inner loop only.
We can use Java continue statement in all types of loops such as for loop, while loop and do-while loop.
for example
class Example{
public static void main(String args[]){
System.out.println("Start");
for(int i=0; i<10; i++){
if(i==5){continue;}
System.out.println("i : "+i);
}
System.out.println("End.");
}
}
output:
Start
i : 0
i : 1
i : 2
i : 3
i : 4
i : 6
i : 7
i : 8
i : 9
End.
[number 5 is skip]
I'm a bit late to the party, but...
It's worth mentioning that continue is useful for empty loops where all of the work is done in the conditional expression controlling the loop. For example:
while ((buffer[i++] = readChar()) >= 0)
continue;
In this case, all of the work of reading a character and appending it to buffer is done in the expression controlling the while loop. The continue statement serves as a visual indicator that the loop does not need a body.
It's a little more obvious than the equivalent:
while (...)
{ }
and definitely better (and safer) coding style than using an empty statement like:
while (...)
;
continue must be inside a loop Otherwise it showsThe error below:
Continue outside the loop