I often see code like:
Iterator i = list.iterator();
while(i.hasNext()) {
...
}
but I write that (when Java 1.5 isn't available or for each can't be used) as:
for(Iterator i = list.iterator(); i.hasNext(); ) {
...
}
because
It is shorter
It keeps i in a smaller scope
It reduces the chance of confusion. (Is i used outside the
while? Where is i declared?)
I think code should be as simple to understand as possible so that I only have to make complex code to do complex things. What do you think? Which is better?
From: http://jamesjava.blogspot.com/2006/04/iterating.html
I prefer the for loop because it also sets the scope of the iterator to just the for loop.
There are appropriate uses for the while, the for, and the foreach constructs:
while - Use this if you are iterating and the deciding factor for looping or not is based merely on a condition. In this loop construct, keeping an index is only a secondary concern; everything should be based on the condition
for - Use this if you are looping and your primary concern is the index of the array/collection/list. It is more useful to use a for if you are most likely to go through all the elements anyway, and in a particular order (e.g., going backwards through a sorted list, for example).
foreach - Use this if you merely need to go through your collection regardless of order.
Obviously there are exceptions to the above, but that's the general rule I use when deciding to use which. That being said I tend to use foreach more often.
Why not use the for-each construct? (I haven't used Java in a while, but this exists in C# and I'm pretty sure Java 1.5 has this too):
List<String> names = new ArrayList<String>();
names.add("a");
names.add("b");
names.add("c");
for (String name : names)
System.out.println(name.charAt(0));
I think scope is the biggest issue here, as you have pointed out.
In the "while" example, the iterator is declared outside the loop, so it will continue to exist after the loop is done. This may cause issues if this same iterator is used again at some later point. E. g. you may forget to initialize it before using it in another loop.
In the "for" example, the iterator is declared inside the loop, so its scope is limited to the loop. If you try to use it after the loop, you will get a compiler error.
if you're only going to use the iterator once and throw it away, the second form is preferred; otherwise you must use the first form
IMHO, the for loop is less readable in this scenario, if you look at this code from the perspective of English language. I am working on a code where author does abuse for loop, and it ain't pretty. Compare following:
for (; (currUserObjectIndex < _domainObjectReferences.Length) && (_domainObjectReferences[currUserObjectIndex].VisualIndex == index); ++currUserObjectIndex)
++currNumUserObjects;
vs
while (currUserObjectIndex < _domainObjectReferences.Length && _domainObjectReferences[currUserObjectIndex].VisualIndex == index)
{
++currNumUserObjects;
++currUserObjectIndex;
}
I would agree that the "for" loop is clearer and more appropriate when iterating.
The "while" loop is appropriate for polling, or where the number of loops to meet exit condition will change based on activity inside the loop.
Not that it probably matters in this case, but Compilers, VMs and CPU's normally have special optimization techniques they user under the hood that will make for loops performance better (and in the near future parallel), in general they don't do that with while loops (because its harder to determine how it's actually going to run). But in most cases code clarity should trump optimization.
Using for loop you can work with a single variable, as it sets the scope of variable for a current working for loop only. However this is not possible in while loop.
For Example:
int i; for(i=0; in1;i++) do something..
for(i=0;i n2;i+=2) do something.
So after 1st loop i=n1-1 at the end. But while using second loop you can set i again to 0.
However
int i=0;
while(i less than limit) { do something ..; i++; }
Hence i is set to limit-1 at the end. So you cant use same i in another while loop.
Either is fine. I use for () myself, and I don't know if there are compile issues. I suspect they both get optimized down to pretty much the same thing.
I agree that the for loop should be used whenever possible but sometimes there's more complex logic that controls the iterator in the body of the loop. In that case you have to go with while.
I was the for loop for clarity. While I use the while loop when faced with some undeterministic condition.
Both are fine, but remember that sometimes access to the Iterator directly is useful (such as if you are removing elements that match a certain condition - you will get a ConcurrentModificationException if you do collection.remove(o) inside a for(T o : collection) loop).
I prefer to write the for(blah : blah) [foreach] syntax almost all of the time because it seems more naturally readable to me. The concept of iterators in general don't really have parallels outside of programming
Academia tends to prefer the while-loop as it makes for less complicated reasoning about programs. I tend to prefer the for- or foreach-loop structures as they make for easier-to-read code.
Although both are really fine, I tend to use the first example because it is easier to read.
There are fewer operations happening on each line with the while() loop, making the code easier for someone new to the code to understand what's going on.
That type of construct also allows me to group initializations in a common location (at the top of the method) which also simplifies commenting for me, and conceptualization for someone reading it for the first time.
Related
I would like to know which one is good. I am writing a for loop. In the condition part I am using str.length(). I wonder is this a good idea. I can also assign the value to an integer variable and use it in the loop.
Which one is the suitable/better way?
If you use str.length() more than once or twice in the code, it's logical to extract it to a local var simply for brevity's sake. As for performance, it will most probably be exactly the same because the JIT compiler will inline that call, so the native code will be as if you have used a local variable.
There is no distinct downside to calling a function in the loop condition expression in the sense that "you really should never do it". You want to watch out when calling functions that have side effects, but even that can be acceptable in some circumstances.
There are three major reasons for moving function calls out of the loop (including the loop condition expressions):
Performance. The function may (depending on the JIT compiler) get called for every iteration of the loop, which costs you execution time. Particularly if the function's code has a higher order of complexity than O(1) after the first execution, this will increase the execution time. By how much depends entirely on exactly what the function in question does and how it is implemented.
Side effects. If the function has any side effects, those may (will) be executed repeatedly. This might be exactly what you want, but you need to be aware of it. A side effect is basically something that is observable outside of the function that is being called; for example, disk or network I/O are often considered to be side effects. A function that simply performs calculations on already available data is generally a pure function.
Code clarity. Admittedly str.length() isn't very long, but if you have a complex calculation based around a function call in the loop conditional, code clarity can very easily suffer. For this reason it may be advantageous to move the loop termination condition calculation out of the loop condition expression itself. Beware of awakening the sleeping beast, however; make very sure that the refactored code actually is more readable.
For str.length() it doesn't really matter unless you are really after the last bit of performance you can get, particularly as as has been pointed out by other answerers, String#length() is an O(1) complexity operation. Especially in the general case, if you need the additional performance, consider introducing a variable to hold the result of the function call and comparing against that rather than making the function call repeatedly.
Personally, I'd consider code clarity before worrying about micro-optimizations like exactly where to place a specific function call. But if you have everything else down and still need to ooze a little bit more performance out of the code, moving the function call out of the condition expression and using a local variable (preferably of a primitive type) is something worth considering. Chances are, though, that if you are worried about that, you'll see bigger gains by considering a different algorithm. (Do you really need to iterate over the string the way you are doing? Is there no other way to do what you are after?)
It usually doesn't matter. Use whichever makes your code clearer.
If a value is going to be used more than once, then there are two advantages to assigning it to a local variable:
You can give the variable a good name, which makes your code easier to read an understand
You can sometimes avoid a small amount of overhead by calling the method only once. This helps performance (although the difference is often too small to be noticeable - if in doubt you should benchmark)
Note: This advice only applies to pure functions. You need to be much more careful if the function has side effects, or might return a different value each time (like Math.random()) - in these cases you need to think much more carefully about the effect of multiple function calls.
Calling length costs O(1) since the length is stored as a member - It's a constant operation, don't waste your time thinking about complexity and performance of this thing.
there are no difference at all between the two
But suppose if the str.length changes then in the for loop you need to manualy change the value
for example
String str="hi";
so in the for loop you write this way
for int i=0;i<str.length();i++)
{
}
or
for int i=0;i<2;i++)
{
}
Now suppose you want to change the str String str="hi1";
so in the for loop
for int i=0;i<3;i++)
{
}
So I would suggest you to go for str.length()
If you use str.length always this will evaluated. It is better to assign this value to variable and use that in for loop.
for(int i=0; i<str.length;i++){ // str.length always evaluvated
}
int k=str.length; // only one time evaluvated
for(int i=0;i<k;i++){
}
If you are concern about performance you may use second approach.
If you are using str.length() in the code more than one time then you need to assign it to another variable and use it. Otherwise you can use str.length() itself.
Reason for need
When we call a method, each time the current position is stored in a DS (heap/stack) and go to the corresponding called method and make their operations
And come back and from the DS retrieve the current position and do the normal operations.
That is actually happening. So when we do it so many times in a program it will cause the above mentioned scenario for several times.
Therefore we need to create a local variable and assign into it and use where ever need in the program.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
for loop optimization
In java i have a block of code:
List e = {element1, element2, ...., elementn};
for(int i = 0; i < e.size(); i++){//Do something in here
};
and another block:
List e = {element1, element2, ...., elementn};
int listSize = e.size();
for(int i = 0; i < listSize; i++){//Do something in here
};
I think that the second block is better, because in the first block, if i++, we have to calculate e.size() one more times to compare the condition in the for loop. Is it right or wrong?
And comparing the two block above, what is the best practice for writing for? And why?Explain clearly and try this loop yourself
Personally I'd use the enhanced for statement instead:
for (Object element : e) {
// Use element
}
Unless you need the index, of course.
If I had to use one of the two forms, I'd use the first as it's tidier (it doesn't introduce another local variable which is only used in that loop), until I had concrete evidence that it was causing a problem. (In most list implementations, e.size() is a simple variable access which can be inlined by the JIT anyway.)
Usually, the most brief and readable code is the best choice, all things being equal. In the case of Java, the enhanced for loop (which works with any class that implements Iterable) is the way to go.
for (Object object : someCollection) { // do something }
In terms solely of the two you posted, I think the first is the better option. It's more readable, and you have to remember that, under the hood, JIT will attempt to optimize a great deal of the code you write anyway.
EDIT: Have you heard the phrase "premature optimisation is the root of all evil"? Your second block is an example of premature optimisation.
If you check the size() implementation on a LinkedList class, you will find that the size is incemented or decremented when an element is added or removed from the list.
Calling size() just returns the value of this property and does not involve any calculation.
So directly calling size() method should be better as you will save on the save for another integer.
I would always use (if you need an index variable):
List e = {element1, element2, ...., elementn};
for(int i = 0, size = e.size(); i < size; i++){
// Do something in here
};
Since e.size() could be an expensive operation.
Your 2nd option is not good, since it introduces a new variable outside of the for loop. I recommend to keep variable visibility as limited as possible.
Otherwise a
for (MyClass myObj : list) {
// Do something here
}
is even cleaner, but might introduce a small performance hit (the index approach doesn't require to instantiate an Iterator).
Yes, the second form is marginally more efficient as you don't repeated perform the size() method invocation. Compilers are good are doing this sort of optimisation themselves.
However, it's unlikely that this would be the performance bottleneck of your application. Avoid premature optimisation. Make your code clean and readable foremost.
HotSpot will move e.size() from cycle in most cases. So it will calculate size of List only once.
As for me I prefer the following notation:
for (Object elem: e) {
//Do something
}
i think this should be much more better..
may be initializing the int variable every time can be escaped from this..
List e = {element1, element2, ...., elementn};
int listSize = e.size();
int i=0;
for(i = 0; i < listSize; i++){//Do something in here
};
Second one is better approach because in the first block, you are calling the e.size() is a method which is an operation in a loop that is a extra burden to JVM.
Im not so sure but i think the optimizer of java will replace the value with a static value, so in the end it will be the same.
To avoid all this numbering and iterators and checkings in writing the code use the following simple most readable code that has its performance to maximum.
Why this has maximum performance (details are coming up)
for (Object object : aCollection) {
// Do something here
}
If the index is needed then:
To choose between the above two forms:
The second is the better as you said because it only calculated the size once.
I think now we have a tendency to write short and understandable code, so the first option is better.
the second is better , cos in the firt loop in the body of it maybe u will do this statment
e.remove, and then the size of e will be changed , so it is better to save the size in a parameter before the looop
Given the need to loop up to an arbitrary int value, is it better programming practice to convert the value into an array and for-each the array, or just use a traditional for loop?
FYI, I am calculating the number of 5 and 6 results ("hits") in multiple throws of 6-sided dice. My arbitrary int value is the dicePool which represents the number of multiple throws.
As I understand it, there are two options:
Convert the dicePool into an array and for-each the array:
public int calcHits(int dicePool) {
int[] dp = new int[dicePool];
for (Integer a : dp) {
// call throwDice method
}
}
Use a traditional for loop:
public int calcHits(int dicePool) {
for (int i = 0; i < dicePool; i++) {
// call throwDice method
}
}
My view is that option 1 is clumsy code and involves unnecessary creation of an array, even though the for-each loop is more efficient than the traditional for loop in Option 2.
At this point, speed isn't important (insert premature-optimization comment ;). What matters is how quickly you can understand what the code does, which is to call a method dicePool times.
The first method allocates an array of size dicePool and iterates through its values, which happens to run the loop body dicePool times (I'll pretend you meant int instead of Integer to avoid the unrelated autoboxing issue). This is potentially inefficient for the computer running the code, but more importantly it's inefficient for the human reading the code as it's conceptually distant from what you wanted to accomplish. Specifically, you force the reader to think about the new array you've just made, AND the value of the variable a, which will be 0 for every iteration of the loop, even though neither of those are related to your end goal.
Any Java programmer looking at the second method will realize that you're executing the loop body dicePool times with i 'counting up' to dicePool. While the latter part isn't especially important, the beginning is exactly what you meant to do. Using this common Java idiom minimizes the unrelated things a reader needs to think about, so it's the best choice.
When in doubt, go with simplicity. :D
Why would you need to allocate an array to loop over a variable that can be safely incremented and used without any need of allocation?
It sounds unecessarily inefficient. You can need to allocate an array if you need to swap the order of ints but this is not the case. I would go for option 2 for sure.
The foreach is useful when you want to iterate on a collection but creating a collection just to iterate over it when you don't need it is just without sense..
(2) is the obvious choice because there's no point in creating the array, based on your description. If there is, of course things change.
What makes you think that the for-each loop is more efficient?
Iterating over a set is very likely less efficient than a simple loop and counter.
It might help if you gave more context about the problem, specifically whether there's more to this question than choosing one syntax over the other. I am having trouble thinking of a problem to which #1 would be a better solution.
I wouldn't write the first one. It's not necessary to use the latest syntax in every setting.
Your instinct is a good one: if it feels and looks clumsy, it probably is.
Go with #2 and sleep at night.
Why was this loop introduced in java?Is it a java creation? What is its purpose(increases memory/cpu utilisation efficiency)?
Why was this loop introduced in java?
It's just to ease looping over generic collections and arrays. Instead of
for (int i = 0; i < strings.length; i++) {
String string = strings[i];
// ...
}
you can just do
for (String string : strings) {
// ...
}
which makes the code more readable and better maintainable.
Is it a java creation?
No, it existed in other languages long before Java. Java was relatively late in implementing it.
What is its purpose?
See the first answer.
To learn more about it, checkout the Sun guide on the subject.
Update: this does not mean that it makes the other kinds of loops superfluous. the for loop using index is still useful if you'd like to maintain a loop counter for other purposes than getting the item by index. The for loop using an iterator is still useful if you'd like to remove or change elements of the collection itself inside a loop.
It masks the use of iterators, which are heavy and clumsy to use. There are many, many instances where you just want to iterate over a collection without working about its index. The java foreach structure makes this possible.
Please see Foreach:
For each (or foreach) is a computer
language idiom for traversing items in
a collection. Foreach is usually used
in place of a standard for statement.
Unlike other for loop constructs,
however, foreach loops 1 usually
maintain no explicit counter: they
essentially say "do this to everything
in this set", rather than "do this x
times". This avoids potential
off-by-one errors and makes code
simpler to read. In object-oriented
languages an iterator, even if
implicit, is often used as the means
of traversal.
Several languages, including Python,
have only a foreach loop, requiring
explicit counting to achieve
"standard" for behavior.
And specifically the section on Java:
A foreach-construct was introduced in JDK 5.0. Official sources use several names for the construct. It is referred to as the "Enhanced for Loop" the "For-Each Loop" and the "foreach statement".
It's really just Java's imitation of a functional construct that's been around much longer, it's called map. The reason for implementing it is that it is common to make a loop that simply performs an action to every element of a container without regard to it's index. Java's for(element : container) { doSomethingWith(element); } syntax is just a cleaner way to do it than the alternatives, which are either to make a for loop with an index
for(int i=0; i<container.size(); ++i) { doSomethingWith(container.at(i)); }
which is longer and creates a needless index variable, or to do a loop with an iterator
Iterator it = container.iterator();
while(it.hasNext()) { doSomethingWith(it.next()); }
which is also longer. This loop is essentially what the for( : ) {} loop gets compiled as, although there may be some slight differences (I haven't actually seen the bytecode).
It is plain "Syntactic sugar"
Dont think there is any efficiency improvement.
Java community wanted the language to be a bit modernized, competing with C# and Ruby..
This question already has answers here:
How do I break out of nested loops in Java?
(37 answers)
Closed 5 years ago.
I have four foreach loops that iterate through the collections and based on a condition do something.
Here is the code that I am writing now:
boolean breakFlag = false;
String valueFromObj2 = null;
String valueFromObj4 = null;
for(Object1 object1: objects){
for(Object2 object2: object1){
// I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
// Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
// Compare with valueFromObj2 to decide either to break all the foreach loop
breakFlag = compareTwoVariable(valueFromObj2, valueFromObj4 );
if(breakFlag){break;}
} // fourth loop ends here
if(breakFlag){break;}
} // third loop ends here
if(breakFlag){break;}
} // second loop ends here
if(breakFlag){break;}
} // first loop ends here
The main object (objects in the code) comes from a third-party provider SDK, so I cannot change anything on that portion. I want to ask the Stack Overflow community if there is a better approach to break all the four foreach loops. Or if there is any other way to refactor this code to make it more readable and maintainable.
Use a label on the outermost loop, and include this label in the break statement when you want to jump out of all the loops. In the example below, I've modified your code to use the label OUTERMOST:
String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
for(Object2 object2: object1){
//I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
//Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
//Compare with valueFromObj2 to decide either to break all the foreach loop
if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
break OUTERMOST;
}
}//fourth loop ends here
}//third loop ends here
}//second loop ends here
}//first loop ends here
Extract all the loops into the function and use return.
You could use a labeled break statement.
This kind of break terminates an outer statement
See The break Statement
See the Branching Statements Java Tutorial for the easiest way, using a label. You can label any or all of the for loops, then use break or continue in conjunction with those labels.
An alternative to using labels is to use return instead. Just refactor your code into a method call to bypass the need to use labels at all.
Your example is rather generic so it's hard to say what's going on but I'm getting such a a strong code smell from the code you provided that I'm forced to think there has to be another way to do the thing entirely, most likely through refactoring the actual data structure to something more meaningful.
What kind of list objects is? What other (most likely important) data it contains? If it's not too much of a hassle, I'd appreciate if you provided more relevant code since the refactorer in me is getting all giddy just from seeing that pile of loops.
One way to break, or collapse several statements (actually stack frames) is to throw an exception but this is not recommended because it really expensive for the run-time to unwind the stack and it could lead to really nasty difficult to debug undefined behavior, (keep this in mind).
Otherwise, what I recommend, rewrite that code to be able to break out of the loop in a graceful manner. If you cant change this code in any other way, well then you'll have to result to exceptions...
Throw an exception and catch it outside the loops? Use something that's "considered harmful?"
It's a bit funny when computer science paints itself into a corner ;-)
The straightforward solution is to put the entire search process in a method and return as soon as you have an answer.
However, the abstract form of your sample code leaves some other possibilities in question. For instance, is there a way to "index" some of the content (e.g. using Map instances) so that you don't have to use brute-force loops?
Apart from the fact that Java supports labelled break, see also Is it possible to exit a for before time in C++, if an ending condition is reached? which is a similar question with some other relevent solutions.