I am using a Do While loop but i have to test whether that condition is met half way through the loop so that if it is met it will skip that part. Is there an efficient way of doing this?
e.g. I currently have something like this:
do {
method1;
if (!condition)
method2;
} while (!condition);
EDIT: I apologise, i don't think i made it clear in the first place. The condition starts as being false, and at some point during the loop one of the methods will set the (global) "condition" to true at which point i want the loop to immediately end. I just think it's messy having to test the ending condition of the loop within it and was wondering if there was anything obvious i was missing.
Please provide more info about methods. If you can return condition from method1/2, then try:
do {
method1;
} while (!condition && !method2)
or if you pass by reference and method return always true:
while (method1 && !condition && method2 && !condition);
or:
while (!method1 && !method2);
EDIT: if:
public boolean method1/2 { ... logic ... ; condition = true; return condition;}
it's hardly depend on what you will do.
I assume that your are looking for is avoiding this additional test for efficiency because "condition" is not met most of the time (1 out of many)...
This optimization may be done by going deeper into what is really done in method1 and method2 (or on the data they are handling) and add a first "fake step" outside of the loop that will disable treatment of method2 only the first time. Would look like this:
prepare_for_loop_entering
do {
method2
method1;
} while (!condition);
if condition is the same on all the places you refer to it than
do {
method1;
method2;
} while (!condition);
as in your while loop condition will always be false (!condition will be true) unless you set it to true in method1; than you can just break; as soon as you set it to true in method1;
How about this:
method1;
while (!condition) {
method2;
method1;
}
what about this:
while (!condition) {
method1;
if(!condition)
method2;
}
How about the code below:
if(condition)
break;
Use the most generic form of a loop:
while (true)
{
method1;
if (!condition) break;
method2;
}
Further explanation
A while loop with a condition "condition" is exactly like:
while (true)
{
if (condition) break;
method1;
method2;
}
And a do-while is exactly like:
while (true)
{
method1;
method2;
if (condition) break;
}
We want neither of those, hence the code above.
Related
I just found one thing that bothers me and left me puzzled:
I have a method that looks like this:
if( condition1){}
else if(....){}
if(){} // this is confusing, does it matter if it becomes else if?
//Would the behavior change?
else if(){}
else if(){}
Of course it matters. An else if condition is only evaluated if all the preceding if and else-if conditions of the same if-else-if block were false.
An if condition will always be evaluated, since it starts a new if-else-if block.
You should choose between the two based on the required logic.
if( condition1){}
else if(....){} // this condition is only evaluated if all the preceding
// conditions were false
if(){} // this condition will be evaluated regardless of the result of
// evaluation the preceding conditions
else if(){}
else if(){}
if(condition1)
.
.
else if(....){}
after else if(), if you add if (condition ..) statement then it will be considered separate if else block .
If your third if becomes else-if, it will be evaluated only when the first if-else if is false
If you leave it like that, it will be evaluated regardless whether the first if-else if is true or false
As others have pointed out, it does matter. But in case it helps, let me point out an important fact: there's no such thing as else if!
An else keyword is followed by a single statement. There are lots of kinds of statements: method invocations, value assignments... and blocks.
if (condition1)
doSomething();
else
doSomethingElse(); // a method invocation statement
// or...
if (condition2)
doSomething();
else { // a block statement, which itself contains statements
soSomethingElse();
andAnotherThing();
}
This should all look familiar, but consider that an if-else is itself a statement:
// *all* of this is just a single statement, the if-else statement
if (condition3) {
doYetAnotherThing();
} else {
doEvenAnotherThing();
}
Putting this all together, an else if is really just an else whose statement is itself an if-else. The following are exactly equivalent:
// the syntax you're used to:
if (condition1) {
doSomething();
} else if (condition2) {
doAnotherThing();
} else {
doAThirdThing();
}
// the same exact thing, written slightly more verbosely:
if (condition1) {
doSomething();
} else {
if (condition2) { // note that this if-else is within the else{...}
doAnotherThing();
} else {
doAThirdThing();
}
}
And that's really why the "plain" if in the middle of your stream of else-ifs starts a new line of questioning. Without the else in front of it, the previous if is just a plain if, not an if-else -- and thus that "nesting" doesn't happen.
Taking that last example I posted, and removing the else from before the if (condition2), we'd get:
if (condition1) {
doSomething();
} /*else*/ if (condition2) {
doAnotherThing();
} else {
doAThirdThing();
}
Note that without that else to next the else if(condition2), this is really what it looks like, and nothing more. Now all we need is to use slightly different formatting, and the logic becomes clear:
if (condition1) {
doSomething();
}
if (condition2) {
doAnotherThing();
} else {
doAThirdThing();
}
if else if blocks acts like switch blocks with one difference, As switch directly jump to the code block which matches the input case where as if else if block has to reach each condition to reach a particular code block.
Inserting another if{} block between a chain of if else if will simply create a new chain of if else if block from your newly inserted if blocks.
Regular for-loop
for (int i = 0; i < 10; i++) {
// ...
if (iWantToRepeat) {
i--;
continue;
}
// ...
}
Enhanced for-loop
for (Foo f : Bar) {
// ...
if (iWantToRepeat) {
// What can I put here?
}
// ...
}
Is there any way to repeat an iteration of an enhanced for-loop? I get the feeling there might be because it's based on iterators and if I had access to them I could do it I think.
No, you can't. In every iteration the Iterator procedes by 1 step. However you can use a do-while loop to get the same effect:
for (Foo f : Bar) {
boolean iWantToRepeat;
do {
// ...
iWantToRepeat = //...;
// ...
} while(iWantToRepeat);
}
No, you cannot repeat an element going back in the loop. The only solution is adding a new loop inside the enhanced for. In my opinion this should be the way to do that even in a classic for, going forth and back is not very clean and can be harder to understand when reviewing the code.
for (Foo f: bar) {
boolean notEnough=false;
do {
... //this code will be always executed once, at least
// change notEnough to true if you want to repeat
} while (notEnough);
}
or
for (Foo f: bar) {
boolean notEnough=chooseIfYouWantToRunIt();
while(notEnough) {
... //this code can be not executed for a given element
}
}
You should view the enhanced for loop as purely a shortcut for the 95% of times you just need to iterate through something, without doing anything "unusual" that it doesn't support (modifying what you're iterating through, iterating through some elements more than once, etc.)
However, if your use case falls into one of the above categories, you'll just have to fall back to using the standard for loop (it's hardly that much more code to write, after all, and is certainly much better than hacking around a for each loop to get the same result.)
if (myCondition1 && myCondition2 && myCondition3)
{
...
}
I wrote this code and run successfully. but I got warning about part of (...). The warning is "Dead code". It is just interesting to me. Do u have any idea?
thank u
"Dead code" is code that will never be executed. Most likely one of your conditions is hard-coded to false somewhere, making the conditional inside the if always false.
Dead code means it is never going to execute. E.g.
void someMethod() {
System.out.println("Some text");
return;
System.out.println("Another Some text"); // this is dead code, because this will never be printed
}
Same in case of your condition checking e.g.
String obj = "";
if(obj == null && obj.equals("")) { // here you get warning for Dead code because obj is not null and first condition is false so obj.equals("") will never evaluate
}
Your code inside the block is never reached. The reason is most likely that one of the conditions is always false.
If one or more of myCondition1, myCondition2 and myCondition3 are always false (like private const bool myCondition1 = false;) then that code inside the if will never be executed.
This could occur for a number of reasons. Either the whole of the if block is dead, caused by something like the following:
boolean condition1 = true;
boolean condition 2 = !condition1;
if(condition1 && condition2) {
//This code is all dead
Foo f = fooFactory();
f.barr(new Bazz());
}
Or you unconditionally leave the if block using something like return, break or continue, as shown below:
for(Foo f : foos) {
if(true) {
f.barr(new Bazz());
break;
//Everything after here is dead
System.out.println("O noes. I won't get printed :(");
}
}
Is it possible to mid while loop, return to the beginning of the loop?
Something like this
while(this is true)
{
do stuff...
if(this is true)
{
restart while loop;
}
}
Adding clarity: I did not mean restart as in reset variables, I mean restart in the sense of stopping execution and going on to the next iteration.
the continue keyword will do that
while(this is true)
{
do stuff...
if(this is true)
{
continue;
}
}
Basically, continue stops execution of the loop on the spot, and then goes on to the next iteration of the loop. you can do this with other loops such as for loops too.
Yes it is possible. Java provides labels for loops or statement blocks and it must precede a statement.
Syntax is identifier:
START: while(this is true)
{
do stuff...
if(this is true)
{
continue START;
}
}
There are many more ways to do this but i consider this the simplest method.
[EDIT] Misunderstood the question! This works if you want to restart the loop.
There are many ways you can do it. You can have the while loop in a function and call the function. Such as:
public static void loop(){
while(this is true) {
do stuff...
if(this is true) {
loop();
break; <-- dont forget this!
}
}
}
Is there a way to break out of a while loop before the original condition is made false?
for example if i have:
while (a==true)
{
doSomething() ;
if (d==false) get out of loop ;
doSomething_that_i_don't_want_done_if_d_is_false_but_do_if_a_and_d_are_true() ;
}
Is there any way of doing this?
Use the break statement.
if (!d) break;
Note that you don't need to compare with true or false in a boolean expression.
break is the command you're looking for.
And don't compare to boolean constants - it really just obscures your meaning. Here's an alternate version:
while (a)
{
doSomething();
if (!d)
break;
doSomething_that_i_don't_want_done_if_d_is_false_but_do_if_a_and_d_are_true();
}
Try this:
if(d==false) break;
This is called an "unlabeled" break statement, and its purpose is to terminate while, for, and do-while loops.
Reference here.
break;
Yes, use the break statement.
while (a==true)
{
doSomething() ;
if (d==false) break;
doSomething_that_i_don't_want_done_if_d_is_false_but_do_if_a_and_d_are_true() ;
}
while(a)
{
doSomething();
if(!d)
{
break;
}
}
Do the following
Note the inclusion of braces - its good programming practice
while (a==true)
{
doSomething() ;
if (d==false) { break ; }
else { /* Do something else */ }
}
while ( doSomething() && doSomethingElse() );
change the return signature of your methods such that d==doSomething() and a==doSomethingElse(). They must already have side-effects if your loop ever escapes.
If you need an initial test of so value as to whether or not to start the loop, you can toss an if on the front.