I often heard that it's bad to modify the loop counter in the body of a for loop. The following (bad) example shows what I am talking about.
for (int i=0; i<10; i++) {
i++;
}
I know that this would be allowed within while loops but could anybody explain why this is a bad practice in Java resp. even a problem in any programming language.
Two reasons why this is bad:
Readability. for( a; b; c ) { d; } is a shorthand for a; while( b ) { d; c; } explicitly for the case where you are iterating over a list. It is not strictly needed in the language. The whole point of having it is to imply intent: "I want to iterate over an entire list" or "I want to iterate over part of a list in sequence, then abort when I find something" at most.
If you add an additional increment, that will surprise other people encountering your code. If your c above says ++x or whatever, people will simply assume it loops over all items, just to then find "surprise! not always!".
OTOH, if you use a while loop, people only see the condition, and are alerted that this will be a more complex loop where the increment will not be constant.
Optimiziation. Given the above statement of intent, some optimizers will generate different code for a for statement than a while statement. Although none of them should generate wrong code, they might apply an optimization that has worse performance characteristics for non-sequential access than for sequential access.
And by "worse performance characteristics" I mean they may tell the CPU to cache the wrong code path and slow down your execution by a fraction of a cycle because data may have to be loaded into the CPU again after having needlessly been flushed.
Just look at what happens with this code:
1 for (int i=0; i<10; i++) {
2 i++;
3 }
Initially line 1 i=0.
Line 2 increments i, which now equals 1.
End of loop, so i++ takes effect, now i=2.
And so on ...
So if you really wanted to do something like this, you could have wrote it like:
for (int i=0; i<10; i+=2) {
}
Which gets the same result. It's not necessarily bad code, but it doesn't make sense to code like that, and it's very hard to troubleshoot.
Mainly because most of the programmers use it that way, so it is more readable for everyone as mentioned by #AntonH.
Side note: trying as in other language (like C if memory serves) to write:
for(int i =0; i< 10; i){
printf("%d", i);
i++;
}
This code compiles and run. In Java, the equivalent:
for(int i =0; i< 10; i){
System.out.println("%d", i);
i++;
}
Edited thanks to #David Wallace:This yields a compilation error, it is mandatory to have an assignement in the statement part of the for loop.
Related
When it comes to counting, should a do-while loop be used, or a for loop? Because this:
class Main {
public static void main(String[] args) {
int times = 1;
do {
System.out.println("I have printed " + times + " times.");
times++;
} while (times < 6);
}
}
Seems to do the exact same thing as this:
class Main {
public static void main(String[] args) {
for (int times = 1; times < 6; times++) {
System.out.println("I have printed " + times + " times.");
}
}
}
Is it a difference in speed? Preference? Situation? Personal quirks? Some kind of "Java social taboo"? I have no idea. Either seem to be able to be used for effective counting, just that one takes a lot more. And both print the exact same thing.
System.out.println("Many thanks!!");
You're right, these do the same thing (except one starts counting at 0 and the other at 1, but that's just an implementation detail). If your program knows in advance (before the loop starts) how many times you want the loop to iterate, most Java developers will tell you to go with a for loop. That's what it's designed for.
A while loop or do while loop is better suited for situations where you're looking for a specific value or condition before you exit the loop. (Something like count >= 10 or userInput.equals("N"). Anything that evaluates to a boolean True/False value.)
When faced with these kind of dilemmas, aim for readability and familiarity. You should not concern yourself with micro-optimizations. Focus on readability and clearly conveying you intent. Do as other do in similar situation.
Like #Bill-The-Lizard said, while loop suggests to the reader of your code that you opted for it, because you're not counting, but repeating until a condition is met. At least once - otherwise you'd have chosen while(...){ } loop.
In other words, for, do {} while() and while() { } generally work the same. But one may better convey you intent in your particular piece of logic.
I think it's more of a readability and syntactic sugar. This while condition
while (condition)
can also be written as
for (; condition; )
but obviously the first one looks lot better and is more readable.
It depends on the programmer's choice when to use for loop or do while loop but the general practice followed by most of the programmers is
For loop
When you know that the loop will execute a predefined number of times(general practice since you can also use for(;true;) which loops forever).
For example a loop which runs 10 times or n number of times where n is a variable
for(int i = 0; i < n; i++) {
//Do something
}
While loop
When you know that the loop should terminate after the evaluation of a specific condition as true or else you want the loop to run forever (like while(true)) and check the break conditions inside the while loop.
Also the while loop is preferred when you can't figure out the conditions in the first place and start with while(true) but once you write code inside the loop you get good understanding of what's happening and get the idea about which conditions to check thus when to exit the loop.
For example
while(x != 0) {
//Do something;
x--;
}
while(true) {
// some code to execute on which the condition depends
if(condition is true) {
break;
}
}
Do while loop
Do while loop is similar to the while loop but with a small difference. That is it allows the first iteration to happen without checking the condition(specified in the while statement, but you can still evaluate the condition inside the block(curly braces)).
By convention most Java developers use for loops. Effective Java recommends for loops instead of while loops because the loop variable can use a tighter scope which reduces bugs. http://www.corejavaguru.com/effective-java/items/45
Recent versions of Java also allow the following
IntStream.range(0, 6).forEach(
i -> System.out.println("I have printed " + i + " times.")
);
Beyond personal preferences, this one has the advantage that the index is maintained by the runtime and there is no need for the programmer to ++i
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am beginner for the programming language , I am bit confused in the basic of looping concept can any one please tell me clearly when to use the concept of For loop and when to use the while loop so that it would be very grace full for me to my future programming,
Thanks in advance
Generally, you use a for loop if you know (Or the program can know at the time of the loop) how many times you want to run a piece of code, and while loops if you do not.
However, it is possible to use them interchangably, so while it may be a bit less elegant to use one than the other, it doesn't matter too much.
Ex:
for(int i = 0; i < 100; i++){
do stuff
}
is the same as
int i = 0;
while(i < 100){
do stuff
i++;
}
, but the former looks more elegant.
Similarly,
bool condition = false;
while(condition){
do stuff
}
and
for(bool condition = false; condition;){
do stuff
}
are the same, but generally, the while loop is considered more elegant here.
In almost all cases you could use either for or while loops. You are provided with two ways of looping to help reduce the complexity of your code across different use cases.
When to use for loops
For loops are best when you know how many iterations you want to loop before you begin. For example, if you knew you wanted to print the numbers 1 through 10 in order you know you want to loop 10 times.
for(int i = 1; i <= 10; i++)
{
System.out.println(i);
}
When to use while loops
While loops are best when you want to continue looping until a specific event occurs or a condition is met. For example, let's say you wanted to print random numbers between 1 and 10 until you came across the number 5. This may take one iteration or hundreds depending on your luck.
Random rand = new Random();
int value = 0;
while(value != 5)
{
value = rand.nextInt(10);
System.out.println(value);
}
Basically you should use a for loop if you know the number of iterations this loop has to do. Even if that number is a variable (like the length of a list) it is know at runtime.
A while loop is used when you don't know the number of iteration. You mostly check a condition that can evaluate to false after any number.
You also have the do-while and the for-each loops at your disposal. The do-while is used when you know that you have at least one iteration but the number is otherwise unkown. The for-each is used to iterate over arrays and collections. It can do something for each element contained.
A for loop will give you the option to perform any or all of these three things:
Instantiate a starting iteration value (int i = 0)
Define a boolean condition on which iteration may continue (i < 10)
Provide an incrementation step (i += 2)
A valid for loop can look like this:
for(; ;) {
System.out.println("This will run forever!!!");
}
A while loop only gives you the boolean condition, which is mandatory.
You typically use the for loop when:
You know the size of the elements you must iterate over
You typically use the while loop when:
You don't know the size of the elements you must iterate over
You want to busy-wait on some value or variable
For loops are used when you know how many times you need to loop. While loops are used to loop until an event occurs.
Also, note that whatever you can do with a for loop, you can do it with a while loop (just add a variable that increments in the while loop and uses it to break out of the loop when the variable reaches a certain value).
This is one of those things that folks typically pick up by experience. First thing to realise is that any for loop can be decomposed into a while loop
for ( initialise; test ; go on to next )
can be expressed as
initialise;
while(test) {
go on to next
}
I'd suggest trying for a little while to use only while loops. What you will then find is that some of your while loops start to feel a little clumsy.
initialise;
while(test) {
my really interesting code here
go on to next
}
and you find that
for ( initialise ; test; go on to next ) {
my really interesting code here
}
reads more clearly. One common example being working your way through an array.
for ( int i; i < array.length; i++ ){
something with array[i];
}
I have an array:
final int[] exampleArray = new int[ID_DATA_ARRAY_SIZE];
And I can iterate that array several ways, for example:
Way 1:
for (int i = 0; i < exampleArray.length; i++) {
// code where I use 'i' index
}
Way 2:
for (int i = 0; i < ID_DATA_ARRAY_SIZE; i++) {
// code where I use 'i' index
}
Which way is better? Are there any other better ways to do it?
If you don't need i for anything else than extracting the element, then the enhanced for loop looks a bit nicer:
for(int element : exampleArray) {
//code that uses element
}
If you are using i for both accessing the array, and something else, then I would argue Way 1 is best:
for (int i = 0; i < exampleArray.length; i++) {
// code where I use 'i' index
}
The reason is that the next time someone looks at a code, the person will immediately see that you are iterating to the length of the array. If you go for way 2 (using a constant), the reader might wonder if that constant really is the length of your array.
Tackling both performance, and code readability, way 2 is better.
Rated by performance, by using exampleArray.length you are calling upon a "member" variable which requires additional java bytecode to request when compared to calling a "local" variable. But, the difference in performance is extremely minuscule and you would never notice it unless you were making an extreme amount of calculations.
Rated by readability, ID_DATA_ARRAY_SIZE lays out your intent for whomever is reading, which is more important than it may seem. Yet, too many programmers lay out nonsensical or ambiguous variable names, and it makes reading their code lacking in naturalness. Naming variables and functions in a way that makes sense to our minds in an organic way makes the code much simpler to deal with for yourself in the future, and anyone else, making it a good practice.
The fundamental difference in the two approaches, I see is as below:
In Way 1: you use the constant exampleArray.length in the loop condition
In Way 2: you use the constant ID_DATA_ARRAY_SIZE in the loop condition
Obviously way 2 is superior in terms of performance.
This is because you are accessing a constant rather than access member variable of exampleArray object. This advantage is realized in every iteration of the for loop where the value of length member is accessed.
see it is all about personal taste which way you wanna do but whenever you are working with array better to check null for the array and then do your stuff
Say I have a simple PHP loop like this one
// Bad example
$array = array('apple','banana','cucumber');
for ($i = 1; $i < count($array); $i++) {
echo $array[$i];
}
I know this is a bad practice. It's better not using count() inside a loop.
// Nice example
$array = array('apple','banana','cucumber');
$limit = count($array);
for ($i = 1; $i < $limit; $i++) {
// do something...
}
In Java, I would do it this way
// Bad example?
String[] array = {"apple","banana","cucumber"};
for(int i = 0; i < array.length; i++){
System.out.println(array[i]);
}
Question: Isn't this above a bad practice too? Or it is just the same as the example below?
// Nice example?
String[] array = {"apple","banana","cucumber"};
int limit = array.length;
for(int i = 0; i < limit; i++){
System.out.println(array[i]);
}
Any decent compiler/interpreter should automatically optimise the first example to match the second (semantically speaking anyway, if not exactly literally), and probably the third to match the fourth. It's known as a loop invariant optimisation, where the compiler recognises that an entity (variable, expression, etc) does not vary within the loop (i.e. is invariant) and removes it to outside the loop (loosely speaking).
It's not bad practice at all anymore, if it ever was.
The "bad" examples you use are not equivalent, and thus are not comparable - even if they seem so on the surface. Using this description:
for (initialization; termination; increment) {
statement(s)
}
(which is descriptive of both PHP and java loops), the initialization statement is executed once, at the start of the loop. The termination statement and the increment are executed for each iteration of the loop.
The reason it is bad practice to use PHP's count in the termination statement is that, for each iteration, the count function call occurs. In your Java example, array.length is not a function call but a reference to a public member. Therefore, the termination statements used in your examples are not equivalent behavior. We expect a function call to be more costly than a property reference.
It is bad practice to place a function call (or call a property that masks a function) in the termination statement of a for loop in any language which has the described loop mechanics. That's what makes the PHP example "bad", and it would be equally bad if you used a count-type function in Java for loop's termination statement. The real question, then, is whether Java's Array.length does indeed mask a function call - the answer to that is "no" (see the potential duplicate question, and/or check out http://leepoint.net/notes-java/data/arrays/arrays.html)
The main difference is that count() is a function whereas array.length is a property and therefore not different from a limit variable.
They are not the same, in the Java "nice example" you are not calculating the length of the array every time. Instead, you are storing that in the limit variable and using that to stop the calculation instead of the result of calling the length function on the array every iteration through the for loop.
EDIT: Both of the things that you thought were "bad practice" are bad practice and the "nice examples" are the more efficient ways (at least in theory). But it is true that in implementation there will not be any noticeable difference.
In java this doesn't matter an array has this attribute as a constant (public final int).
The difference is in java arrays have a fixed size and can not grow so there would be no need to count the elements every time to access length.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've searched for this, but couldn't find an answer and for whatever reason I was too ashamed to ask professor, due to that feeling when hundreds of people stare at you...
Anyhow, my question is what's the importance of having brackets? Is it OK if I omit them? Example:
for (int i = 0; i < size; i++) {
a += b;
}
vs
for (int i = 0; i < size; i++)
a += b;
I know both of them will work, but if I omit the brackets (which I tend to do a lot, due to visibility) will that change anything, anything at all? As I said, I know it works, I tested it dozen of times, but now some of my uni assignments are getting larger, and for some reason I have irrational fear that in the long run, this my cause some problems? Is there a reason to fear that?
It won't change anything at all apart from the maintainability of your code. I've seen code like this:
for (int i = 0; i < size; i++)
a += b;
System.out.println("foo");
which means this:
for (int i = 0; i < size; i++)
a += b;
System.out.println("foo");
... but which should have been this:
for (int i = 0; i < size; i++) {
a += b;
System.out.println("foo");
}
Personally I always include the brackets to reduce the possibility of confusion when reading or modifying the code.
The coding conventions at every company I've worked for have required this - which is not to say that some other companies don't have different conventions...
And just in case you think it would never make a difference: I had to fix a bug once which was pretty much equivalent to the code above. It was remarkably hard to spot... (admittedly this was years ago, before I'd started unit testing, which would no doubt have made it easier to diagnose).
Using braces makes the code more maintainable and understandable. So you should consider them by default.
I sometimes skip using braces on guard clauses to make the code more compact. My requirement for this is that they're if statements that are followed by a jump statement, like return or throw. Also, I keep them in the same line to draw attention to the idiom, e.g:.
if (!isActive()) return;
They also apply to code inside loops:
for (...) {
if (shouldSkip()) continue;
...
}
And to other jump-conditions from methods that are not necessarily at the top of the method body.
Some languages (like Perl or Ruby) have a kind of conditional statement, where braces don't apply:
return if (!isActive());
// or, more interestingly
return unless (isActive());
I consider it to be equivalent to what I just described, but explicitly supported by the language.
There is no difference. The main problem with the second version is you might end up writing this:
for (...)
do_something();
do_something_else();
when you update that method, thinking that do_something_else() is called inside the loop. (And that leads to head-scratching debug sessions.)
There is a second problem that the brace version doesn't have, and its possibly even harder to spot:
for (int i=0; i<3; i++);
System.out.println("Why on earth does this print just once?");
So keep the braces unless you have a good reason, it is just a few keystrokes more.
I think that loosing curly braces is good, if you are also using auto-format, because than your indentation is always correct, so it will be easy to spot any errors that way.
Saying that leaving the curly braces out is bad, weird or unreadable is just wrong, as whole language is based on that idea, and it's pretty popular (python).
But I have to say that without using a formatter it can be dangerous.
For most cases, the answers mentioned so far are correct. But there are some disadvantages to it from the security perspective of things. Having worked in a payments team, security is a much stronger factor that motives such decisions. Lets say you have the following code:
if( "Prod".equals(stage) )
callBankFunction ( creditCardInput )
else
callMockBankFunction ( creditCardInput )
Now lets say you have this code is not working due to some internal problem. You want to check the input. So you make the following change:
if( "Prod".equals(stage) )
callBankFunction ( creditCardInput )
else
callMockBankFunction ( creditCardInput )
Logger.log( creditCardInput )
Say you fix the problem and deploy this code (and maybe the reviewer & you think this won't cause a problem since its not inside the 'Prod' condition). Magically, your production logs now print customer credit card information that is visible to all the personnel who can see the logs. God forbid if any of them (with malicious intent) gets hold of this data.
Thus not giving a brace and a little careless coding can often lead to breach of secure information. It is also classified as a vulnerability in JAVA by CERT - Software Engineering Institure, CMU.
If you have a single statement you can omit the brackets, for more that one statements brackets is necessary for declaring a block of code.
When you use brackets you are declaring a block of code :
{
//Block of code
}
The brackets should be used also with only one statement when you are in a situation of nested statement for improve readability, so for example :
for( ; ; )
if(a == b)
doSomething()
it is more readable written with brackets also if not necessary :
for( ; ; ) {
if(a == b) {
doSomething()
}
}
If you use brackets your code is more readable.
And if you need to add some operator in same block you can avoid possible errors
Using the brackets future proofs the code against later modifications. I've seen cases where brackets were omitted and someone later added some code and didn't put the brackets in at that time. The result was that the code they added didn't go inside the section they thought it did. So I think the answer is that its good practice in light of future changes to the code. I've seen software groups adopt that as a standard, i.e. always requiring brackets even with single line blocks for that reason.
using redundant braces to claim that code is more maintainable raises the following question: if the guys writing, wondering about and further maintaining the code have issues like the ones described before (indentation related or readability related) perhaps they should not program at all...
Nowadays, it is very easy to re-indent codes to find out which block of codes is in which if or for/while. If you insist that re-indenting is hard to do, then brackets placed at wrong indentation can confuse you equally badly.
for(int i = 0; i < 100; i++) { if(i < 10) {
doSomething();
} else { for(int j = 0; j < 5; j++) {
doSomethingElse();
}
}}
If you do this everywhere, your brain is going to break down in no time. Even with brackets, you are depending on indentation to visually find the start and end of code blocks.
If indentation is important, then you should already write your code in correct indentation, so other people don't need to re-indent your codes to read correctly.
If you want to argue that the previous example is too fake/deliberate, and that the brackets are there to capture careless indentation problem (especially when you copy/paste codes), then consider this:
for(int i = 0; i < 100; i++) {
if(i < 10) {
doSomething();
}
else {
for(int j = 0; j < 5; j++) {
doSomethingElse();
}
}
Yes, it looks less serious than the previous example, but you can still get confused by such indentation.
IMHO, it is the responsibility of the person writing the code to check through the code and make sure things are indented correctly before they proceed to do other things.
More support for the "always braces" group from me. If you omit braces for single-statement loops/branches, put the statement on the same line as the control-statement,
if (condition) doSomething();
for(int i = 0; i < arr.length; ++i) arr[i] += b;
that way it's harder to forget inserting braces when the body is expanded. Still, use curlies anyway.
If you remove braces, it will only read the first line of instruction. Any additional lines will not be read. If you have more than 1 line of instruction to be executed pls use curly brace - or else exception will be thrown.
Result wise , it is the same thing.
Only two things to consider.
- Code Maintainability
- Loosely coupled code. (may execute
something else. because you haven't specified the scope for the loop. )
Note: In my observation, if it is loop with in a loop. Inner Loop without braces is also safe. Result will not vary.
If you have only one statement inside the loop it is same.
For example see the following code:
for(int i=0;i<4;i++)
System.out.println("shiva");
we have only one statement in above code. so no issue
for(int i=0;i<4;i++)
System.out.println("shiva");
System.out.println("End");
Here we are having two statements but only first statement comes into inside the loop but not the second statement.
If you have multiple statements under single loop you must use braces.
it should be a reflex to reformat the code as well... that is of course for professional programmers in professional teams
It's probably best to use the curly braces everywhere for the simple fact that debugging this would be an extreme nuisance. But other wise, one line of code doesn't necessarily need the bracket. Hope this helps!