This is how I would do a while loop:
boolean more = true;
while (more)
{
// do something
if (someTest())
{
more = false;
}
}
That's pretty standard. I'm curious to know if there's a way of doing something similar to the code below in Java: (I think I've seen something like it in C)
// The code below doesn't compile (obviously)
while (boolean more = true)
{
// do something
if (someTest())
{
more = false;
}
}
I only ask this because currently I don't like the way I'm defining the variable used in the condition (in this case: "more") outside the scope of the loop, even though it's only relevant inside the loop. There's no point it being left hanging around after the loop has finished.
* * Update * *
An idea came to me following a visit to the Porcaline Chamber of Secrets:
for (boolean more=true; more; more=someTest())
{
// do something
}
It's not perfect; It's abusing the for loop and I can't think of a way to execute the loop at least once, but it's close... Is there a way to make sure the loop is performed 1+ times?
To answer your question literally, you can do
for(boolean more = true; more; ) {
more = !someTest();
}
but this is much the same as
while(!someTest());
If it must execute at least once you can do
do {
} while(!someTest());
For your specific case, you can reduce your code to this:
while (true) {
if (someTest()) {
break;
}
}
In general, you could replace your outer-scope declaration with an inner-scope one, but you'd need to move the loop condition:
while (true) {
boolean more=true;
...
if (someTest()) {
more = false;
}
...
if (!more) {
break;
}
}
Or even:
do {
boolean more=true;
...
if (someTest()) {
more = false;
}
...
if (!more) {
break;
}
} while (true);
I'd opine that defining your condition outside the loop is clearer.
KidTempo, in the example you gave, I think that more would be re-initialized each time through the loop. Each time through the loop, the conditional is re-evaluated, so assuming that you are able to define a variable in a conditional, the variable would be re-initialized each time that conditional is re-evaluated. This would also apply to other types of conditionals, so I would say to avoid defining variables in a conditional.
Related
I wrote a piece of code which should be executed until the condition is satisfied. I have 2 classes using the same structure. In one of them while (true) loop executes as expected; in the other class the program exits the loop after the first recursion.
protected static boolean flag = true;
private static int value=0;
private static int limit=10;
.
.
.
public static int method(){
if (limit-value <=0)
{
...
}
else {
while(flag) {
if (limit-value > 0 ) {
*the action I want to perform until the condition is satisfied*
value++;
}
else if (limit==value)
{
flag = false;
}
return int_Value;
}
}
}
return int_Value;
}
I expect the while(true) loop to be executed until the condition is satisfied (which is more than once).
With some cleaned up indentation it becomes clear that the while loop contains an unconditional return.
if you look at your code the while loop goes like this
while(flag) {
if (limit-value > 0 ) {
*the action I want to perform until the condition is satisfied*
value++;
}
else if (limit==value)
{
flag = false;
}
return int_Value;
}
after executing either if or if else statement there is a return int_value statement which is causing the problem
Although I did debugging I couldn't see it in the first place. I performed another debug session after #user3437460 's suggestion, so I was able to find out:
It seems like an additional return statement was used!(return int_Value;),
the one after else if block. So, the program returns a value and never goes back into the loop.
After deleting the first return statement, program runs just fine.
I have a method with if-else cases, and more than one return statement, depending on the exact flow.
I have one line of code that needs to happen just before the return statement (e.g. releaseResources).
I want to be sure that this line is executed no matter what.
Is there a nice way of doing that in java?
Something that will make sure a piece of code is executed before leaving a closure?
What you are looking for is a try-finally block. Here is an example:
public Something someMethod() {
try {
if(someStatement) {
return new Something();
} else {
return new SomethingElse();
}
} finally {
// this is always executed, even if there is an Exception
}
}
The question is if this is really what you want. It sounds like your code might actually be better (more readable) if it has two methods. Like this:
public Something createSomething() {
if(someStatement) {
return new Something();
} else {
return new SomethingElse();
}
}
public Something someMethod() {
Something something = createSomething();
// Do the thing that always needs to be done
return something;
}
This separates the things you are doing into two methods. Now if the problem is that the first method can throw an exception and you want to do something nonetheless, you can still use a finally. But it might be better to capture and handle the Exception.
Also: You've noted that you want to close a resource. In that case I would suggest you look into try-with-resources:
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
An example here:
private String someMethod() throws IOException {
// Java automatically closes the following Readers:
try (BufferedReader br =
new BufferedReader(new FileReader("/path"))) {
return br.readLine();
}
}
Depending of the programming language you're using, the try-catch-finally exist:
Example from other post about launch code after the if-else
Finally statement will launch when try-catch condition ends
SORRY FOR EDIT
You can use a try/finally block, if that's what you really want.
try {
if (...) return ...;
else if (...) return ...;
else return ...;
} finally {
doSomething();
}
The code in the finally block will always be executed when you leave the try block, in particular at any return statement.
The finally block will always be executed even if an Exception is thrown.
try {
...
if () {
return;
else {
return;
}
} finally {
// Release resources
}
One of the main programming good practices is that each method should have one and only one return statement. If you have many possible values, you tend to keep the value in an object and return it at the end.
E.g:
public int func(boolean condition) {
if(condition) {
return 1;
} else {
return 0;
}
}
should be made like this
public int func(boolean condition) {
int num;
if(condition) {
num = 1;
} else {
num = 0;
}
return num;
}
As you can probably see, it's quite simple to ensure you call your method before return this way, adding it right before the only return.
Of course this is an impossible statement in java (to-date), however ideally I would like to implement it as it is at the heart of many iterations. For example the first multiple times it is called I'm doing it 650,000+ times when it is creating the ArrayList.
Unfortunately the reality is that my actual code does not have the set inside the else loop; thus it will pass over both the add and then the set commands and wasting time.
After that I have it also in another loop where it is only performing the set as the data is already created and this is multi-nested with in many others so it is a lengthy process.
ArrayList<Integer> dataColLinker = new java.util.ArrayList<Integer>();
...
...
public void setLinkerAt( int value, int rowIndex) {
...
while(rowIndex >= dataColLinker.size()) {
dataColLinker.add(value);
} else {
dataColLinker.set(rowIndex, value);
}
Any ideas or theories?
I'm unsure about speeds in java when it comes to if statements and ArrayList commands and so on
Am I missing something?
Doesn't this hypothetical code
while(rowIndex >= dataColLinker.size()) {
dataColLinker.add(value);
} else {
dataColLinker.set(rowIndex, value);
}
mean the same thing as this?
while(rowIndex >= dataColLinker.size()) {
dataColLinker.add(value);
}
dataColLinker.set(rowIndex, value);
or this?
if (rowIndex >= dataColLinker.size()) {
do {
dataColLinker.add(value);
} while(rowIndex >= dataColLinker.size());
} else {
dataColLinker.set(rowIndex, value);
}
(The latter makes more sense ... I guess). Either way, it is obvious that you can rewrite the loop so that the "else test" is not repeated inside the loop ... as I have just done.
FWIW, this is most likely a case of premature optimization. That is, you are probably wasting your time optimizing code that doesn't need to be optimized:
For all you know, the JIT compiler's optimizer may have already moved the code around so that the "else" part is no longer in the loop.
Even if it hasn't, the chances are that the particular thing you are trying to optimize is not a significant bottleneck ... even if it might be executed 600,000 times.
My advice is to forget this problem for now. Get the program working. When it is working, decide if it runs fast enough. If it doesn't then profile it, and use the profiler output to decide where it is worth spending your time optimizing.
I don't see why there is a encapsulation of a while...
Use
//Use the appropriate start and end...
for(int rowIndex = 0, e = 65536; i < e; ++i){
if(rowIndex >= dataColLinker.size()) {
dataColLinker.add(value);
} else {
dataColLinker.set(rowIndex, value);
}
}
boolean entered = false, last;
while (( entered |= last = ( condition ) )) {
// Do while
} if ( !entered ) {
// Else
}
You'r welcome.
Wrap the "set" statement to mean "set if not set" and put it naked above the while loop.
You are correct, the language does not provide what you're looking for in exactly that syntax, but that's because there are programming paradigms like the one I just suggested so you don't need the syntax you are proposing.
Java does not have this control structure.
It should be noted though, that other languages do.
Python for example, has the while-else construct.
In Java's case, you can mimic this behaviour as you have already shown:
if (rowIndex >= dataColLinker.size()) {
do {
dataColLinker.add(value);
} while(rowIndex >= dataColLinker.size());
} else {
dataColLinker.set(rowIndex, value);
}
This while else statement should only execute the else code when the condition is false, this means it will always execute it. But, there is a catch, when you use the break keyword within the while loop, the else statement should not execute.
The code that satisfies does condition is only:
boolean entered = false;
while (condition) {
entered = true; // Set it to true stright away
// While loop code
// If you want to break out of this loop
if (condition) {
entered = false;
break;
}
} if (!entered) {
// else code
}
Assuming you are coming from Python and accept this as the same thing:
def setLinkerAt(value, rowIndex):
isEnough = lambda i: return i < dataColLinker.count()
while (not isEnough(rowIndex)):
dataColLinker.append(value)
else:
dataColLinker[rowIndex] = value
The most similar I could come up with was:
public void setLinkerAt( int value, int rowIndex) {
isEnough = (i) -> { return i < dataColLine.size; }
if(isEnough()){
dataColLinker.set(rowIndex, value);
}
else while(!isEnough(rowInex)) {
dataColLinker.add(value);
}
Note the need for the logic, and the reverse logic. I'm not sure this is a great solution (duplication of the logic), but the braceless else is the closest syntax I could think of, while maintaining the same act of not executing the logic more than required.
Some time ago I came across the following construct which I have rarely seen since, though I use it relatively frequently. I use it typically when checking on a whole list of conditions are true and it prevents large levels of indentation. Essentially it uses a for loop to provide a kind of structured goto. My question is firstly whether there is better way to structure this, secondly whether people like it and thirdly whether a new keyword in java/c++ etc. such as unit { } which would only cause breaks to exit to the end of the unit would be useful and clearer.
ps I realise that it is on slip away from an infinite loop, but I think my paranoia about that has meant its never happened.
Edit: I have added some setup code for the further conditions to try to illuminate problems with chained if then elses
boolean valid = false;
// this loop never loops
for (;;)
{
if (!condition1)
break;
condition2.setup();
if (!condition2)
break;
condition3.setup();
if (!condition3)
break;
valid = true;
break;
}
if (valid) dosomething();
EDIT:
I have just discovered that in fact there is a way to structure this in java without misusing loops etc. and wondered whether this would similarily be frowned on, though I guess I have missed the boat on this one.
The restructured code looks like this.
boolean valid = false;
breakout:
{
if (!condition1)
break breakout;
condition2.setup();
if (!condition2)
break breakout;
condition3.setup();
if (!condition3)
break breakout;
valid = true;
}
if (valid) dosomething();
Now that removes the misuse of the for loop which caused a lot of the complaints, and is actually a solution I think is quite neat and is what I was looking to find originally.
I am guessing that this structure is probably not well known since no one mentioned it, people object to this as strongly?
The loop is counter-intuitive and would be questioned at code review: "Why do you need a loop if you always break on the first iteration?"
Why not use this?
boolean valid = true;
if (!condition1)
valid = false;
else if (!condition2)
valid = false;
else if (!condition3)
valid = false;
if (valid) dosomething();
You may have heard of these things modern programming languages have, called functions ;)
One of the key reasons goto is no longer used is that we can now factor code out into separate functions, and call them instead.
One way to solve your problem would be to put the code in a separate function instead, and return instead of breaking from your pseudo-loop:
void safedosomething() {
if (!condition1)
return;
condition2.setup();
if (!condition2)
return;
condition3.setup();
if (!condition3)
return;
dosomething();
}
or write helper functions (such as bool checkcondition1() { condition1.setup(); return condition1; }) which set up and then test the conditions, and use a boolean flag:
bool valid = true;
if (!checkcondition1())
valid = false;
if (!checkcondition2())
valid = false;
if (!checkcondition3())
valid = false;
if (!checkcondition4())
valid = false;
if (valid) dosomething();
or a bit more concisely:
bool valid = true;
valid &&= checkcondition1();
valid &&= checkcondition2();
valid &&= checkcondition3();
valid &&= checkcondition4();
if (valid) dosomething();
or just
if (checkcondition1()
&& checkcondition2()
&& checkcondition3()
&& checkcondition4())
dosomething();
There are plenty of ways to express this, without counterintuitive loops-that-don't-loop.
The reason for this construct is because goto is a dirty word in programming. But lets face it, you are effectively using the loop construct to do the same thing. My opinion on this is either be honest and use the goto or refactor the code.
I don't think it's the most readable way of doing it. Chained if-else if looks much better. But if you want to stick with it and don't want to be so close to an infinite loop, you could do something like this:
do
{
if (...)
break;
...
} while (false);
C++ only, unfortunately:
if ( condition1
&& (condition2.setup(), condition2)
&& (condition3.setup(), condition3) )
{
dosomething();
}
For something java compatible (but I'm still writing C++!) I would fall back to something along the lines of this. (Obviously, some context may need to be passed into CheckConditions().)
bool CheckConditions()
{
if (!condition1)
return false;
condition2.setup();
if (!condition2)
return false;
condition3.setup();
if (!condition3)
return false;
return true;
}
//...
if (CheckConditions())
{
dosomething();
}
//...
You seem concerned that evaluating condition 2 requires some setup, and you don't know where to put it. Refactor that into a separate boolean method and then use that the way almost everybody here has described. For example:
if (checkCondition1() && checkCondition2(someInput) && checkCondition3()) {
doSomething();
}
and..
private boolean checkCondition2(Object someInput) {
//setup condition 2
return condition2;
}
I think the problem with
if (condition1 && condition2 && ...)
was simply that it could become hard to read and edit if there are lots of conditions, although you could always write it like this:
if ( condition1 &&
condition2 &&
condition3 ... )
doStuff();
How about you turn the loop into a function:
bool all()
{
if (!condition1) return false;
if (!condition2) return false;
if (!condition3) return false;
....
return true;
}
Here's sort of compromise, if you want to keep the indentation as it is:
boolean valid = true; // optimistic start
if (!valid || !condition1)
valid = false;
if (!valid || !condition2)
valid = false;
if (!valid || !condition3)
valid = false;
if (valid)
doSomething();
The !valid in the first if statement is superflucious but doesn't harm, could be kept for readability. else/if is more elegant, to my opinion, but that's just an opinion.
But I really wouldn't (ab-)use the for loop and I never ever would find a cheap way to implement a pseudo-goto. There's always a better solution.
I'm not sure why you need a loop if there is a break statement at the end of the loop. Arent you just iterating once, no matter the situation?
Anyway, you'll usually find two differing opinions concerning this on SO, one being that break statements shouldn't be used at all, and one being that it depends on the situation.
I tend to fall in with the latter group, but the way that your loop works uses superfluous break statements. I'd much rather structure such a loop like this:
bool valid = true;
for(... ; .... && valid == true ; ....)
{
if (!condition1)
valid = false;
if (!condition2)
valid = false;
if (!condition3)
valid = false;
}
This allows a loop exit that I think is more elegant.
Having such a long if statement is most likely bad coding.
It makes it very hard to test, and is most likely a code smell.
If possible you should refactor to take advantage of polymorphism.
How about relocating the setup to the operator bool on the Condition class? This makes it far more readable and hides the mechanics.
class Condition
{
bool _isSet;
public:
Condition() : _isSet(false) {
}
void setup() {
_isSet = true;
}
operator bool () {
if (!_isSet) {
setup();
}
return rand() & 1;
}
};
void doSomething()
{
}
int _tmain(int argc, _TCHAR* argv[])
{
Condition cond1, cond2, cond3;
if (cond1 && cond2 && cond3) {
doSomething();
}
return 0;
}
You can take that code out to a separate function and use multiple return statements. You will likely need to refactor the long list of if statements into a separate function anyway.
bool isValid()
{
if (!condition1)
return false;
condition2.setup();
if (!condition2)
return false;
condition3.setup();
if (!condition3)
return false;
return true;
}
Then you could use it in your code:
if (isValid()) dosomething();
Given the following code snippets, is there any appreciable difference?
public boolean foo(int input) {
if(input > 10) {
doStuff();
return true;
}
if(input == 0) {
doOtherStuff();
return true;
}
return false;
}
vs.
public boolean foo(int input) {
if(input > 10) {
doStuff();
return true;
} else if(input == 0) {
doOtherStuff();
return true;
} else {
return false;
}
}
Or would the single exit principle be better here with this piece of code...
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
Is there any perceptible performance difference? Do you feel one is more or less maintainable/readable than the others?
With the second example you state very clearly that both conditions are mutually exclusive.
With the first one, it is not so clear, and in the (unlikely) event that an assignment to input is added between both ifs, the logic would change.
Suppose someone in the future adds input = 0 before the second if.
Of course this is unlikely to happen, but if we are talking about maintainability here, if-else says clearly that there are mutually exclusive conditions, while a bunch of ifs don't, and they are not so dependent between each other as are if-else blocks.
edit:Now that I see, in this particular example, the return clause forces the mutual exclusivity, but again, we're talking about maintainability and readability.
Anyway, about performance, if this is coded in Java you shouldn't care for performance of a couple of if blocks, if it were embedded C in a really slow hardware, maybe, but certainly not with java.
Use whatever form best describes your intent.
Do not follow the single exit principle if things are this simple, though--it just makes it more confusing.
In the first:
somebody eventually, by some strange reason and when you're not looking will add some add statement that will make this method fail under certain strange conditions, everybody ( or worst, one single person ) will spend 4 hrs. watching the source code and debugging the application to finally found there was something in the middle.
The second is definitely better, not only it prevents this scenario, but also helps to clearly state , it this or this other no more.
If all the code we write within an if where 10 lines long at most, this wouldn't matter really, but unfortunately that's not the case, there exists other programmers which by some reason think that a if body should be > 200 lines long... anyway.
I don't like the third, it forces me to look for the return variable, and it's easier to find the return keyword
About speed performance, they are ( almost ) identical. Don't worry about that.
In your last example, don't do this:
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
but this (notice the use of Java's final):
public boolean foo(int input) {
final boolean toBeReturned; // no init here
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
} else {
toBeReturned = false;
}
return toBeReturned;
}
By doing so you make your intend clear and this is a godsend for IDEs supporting "programming by intention" (there's no need to "compile" to see potential errors, even on a partial AST, a good IDE can examine incomplete source in real-time and give you instant warnings).
This way you are sure not to forget to initialize your return value. This is great if later on you decide that after all you need another condition.
I do this all the time and even moreso since I started using IntelliJ IDEA (version 4 or so, a long time ago) and this has saved me so many silly distraction mistakes...
Some people will argue that this is too much code for such a simple case but that's entirely missing the point: the point is to make the intent clear so that the code reads easily and can be easily extended later on, without accidentally forgetting to assign toBeReturned and without accidentally forgetting to return from a later clause you may add.
Otherwise, if "conciseness" was the name of the game, then I'd write:
public boolean foo(int a) {
return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false;
}
Where both doStuff and doOtherStuff would return true.
Semantically — no. Performance-wise this depends on compiler, i.e. whether it can spot that both conditions cannot be true at once. I'd bet standard Sun compiler can. Whether to use single exit principle depends on tastes. I personally hate it.
Version #1 and #2 may be faster than #3, but I suppose the performance difference is minimal. I would rather focus on readability.
Personally, I would never use version #2. Between #1 and #3, I would choose the one that yields the most readable code for the case in question. I don't like many exit points in my methods, because it makes the code hard to analyze. However, there are cases where the flow becomes clearer when we exit immediately for some special cases, and continue with the main cases.
Think of this case when the two examples won't be similar:
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
System.out.println("do some other intermediary stuff");
if (input == 0) {
// doOtherStuff();
return true;
}
return false;
}
vs.
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
//System.out.println("doing some intermediary stuff... doesn't work");
else if (input == 0) {
// doOtherStuff();
return true;
} else {
return false;
}
return false;
}
The first approach is probably more flexible, but both formulas have their use in different circumstances.
Regarding performance, I think the differences are to small to be taken in consideration, for any regular java application, coded by sane programmers :).
In your case the second if would only get called if the first if failed so it's less important here but if your first if did something and didn't return, the second if (which would then always be false) would still be tested unless it was in an else-if.
In other words, there are cases where the difference between if-else-if and if-if matters, but this isn't one of them.
Example: Try this and then try it after removing the else. You get two different outputs:
int someNumber = 1;
if(someNumber < 5)
{
someNumber += 5;
Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
Console.WriteLine("Second call.");
}
Between the first and second snippets, there's really no difference. However the third snippet is quite inefficient. Because you wait to return control of the program to the caller until the last line of code in the method, you waste processing power/memory whereas the first two code snippets return control as soon as it determines one of the conditions to be true.