I have a for loop, and I am not sure how it works. I am familiar with:
for(int i = 0; i <= 9; i++)
{
/* implementation */
}
I am confused about a for loop in the following form:
String[] myString = new String[] {"one", "two", "three", "some other stuff"};
String str1 = "", str2 = "";
for (String s : myString)
{
/* implementation */
}
How do these types of for loops work? what do they do differently then regular for loops?
The first is the original for loop. You initialize a variable, set a terminating condition, and provide a state incrementing/decrementing counter (There are exceptions, but this is the classic)
For that,
for (int i=0;i<myString.length;i++) {
System.out.println(myString[i]);
}
is correct.
For Java 5 an alternative was proposed. Any thing that implements iterable can be supported. This is particularly nice in Collections. For example you can iterate the list like this
List<String> list = ....load up with stuff
for (String string : list) {
System.out.println(string);
}
instead of
for (int i=0; i<list.size();i++) {
System.out.println(list.get(i));
}
So it's just an alternative notation really. Any item that implements Iterable (i.e. can return an iterator) can be written that way.
What's happening behind the scenes is somethig like this: (more efficient, but I'm writing it explicitly)
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String string=it.next();
System.out.println(string);
}
In the end it's just syntactic sugar, but rather convenient.
There is an excellent summary of this feature in the article The For-Each Loop. It shows by example how using the for-each style can produce clearer code that is easier to read and write.
Using the first for-loop you manually enumerate through the array by increasing an index to the length of the array, then getting the value at the current index manually.
The latter syntax is added in Java 5 and enumerates an array by using an Iterator instance under the hoods. You then have only access to the object (not the index) and you won't be able to adjust the array while enumerating.
It's convenient when you just want to perform some actions on all objects in an array.
The for-each loop was introduced in Java 1.5 and is used with collections (and to be pedantic, arrays, and anything implementing the Iterable<E> interface ... which the article notes):
http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html
Something none of the other answers touch on is that your first loop is indexing though the list. Whereas the for-each loop is using an Iterator. Some lists like LinkedList will iterate faster with an Iterator versus get(i). This is because because link list's iterator keeps track of the current pointer. Whereas each get in your for i=0 to 9 has to recompute the offset into the linked list. In general, its better to use for-each or an Iterator because it will be using Collections iterator, which in theory is optimized for the collection type.
The new for-each loop is just a short hand for the older loop. The new loop is easier to use for arrays and some iterators, but not as flexible, so the old loop has to be using in some situations, like counting from 0 to 9.
The second for loop is any easy way to iterate over the contents of an array, without having to manually specify the number of items in the array(manual enumeration). It is much more convenient than the first when dealing with arrays.
The For-each loop, as it is called, is a type of for loop that is used with collections to guarantee that all items in a collection are iterated over. For example
for ( Object o : objects ) {
System.out.println(o.toString());
}
Will call the toString() method on each object in the collection "objects". One nice thing about this is that you cannot get an out of bounds exception.
Related
I would like to know what are the advantages of Enhanced for loop and Iterators in Java +5 ?
The strengths and also the weaknesses are pretty well summarized in Stephen Colebourne (Joda-Time, JSR-310, etc) Enhanced for each loop iteration control proposal to extend it in Java 7:
FEATURE SUMMARY:
Extends the Java 5 for-each loop to allow access to the
loop index, whether this is the first
or last iteration, and to remove the
current item.
MAJOR ADVANTAGE
The for-each loop is almost certainly the most new
popular feature from Java 5. It works
because it increases the abstraction
level - instead of having to express
the low-level details of how to loop
around a list or array (with an index
or iterator), the developer simply
states that they want to loop and the
language takes care of the rest.
However, all the benefit is lost as
soon as the developer needs to access
the index or to remove an item.
The original Java 5 for each work took
a relatively conservative stance on a
number of issues aiming to tackle the
80% case. However, loops are such a
common form in coding that the
remaining 20% that was not tackled
represents a significant body of code.
The process of converting the loop
back from the for each to be index or
iterator based is painful. This is
because the old loop style if
significantly lower-level, is more
verbose and less clear. It is also
painful as most IDEs don't support
this kind of 'de-refactoring'.
MAJOR BENEFIT:
A common coding idiom is expressed at
a higher abstraction than at present.
This aids readability and clarity.
...
To sum up, the enhanced for loop offers a concise higher level syntax to loop over a list or array which improves clarity and readability. However, it misses some parts: allowing to access the index loop or to remove an item.
See also
Java 7 - For-each loop control access
Stephen Colebourne's original writeup
For me, it's clear, the main advantage is readability.
for(Integer i : list){
....
}
is clearly better than something like
for(int i=0; i < list.size(); ++i){
....
}
I think it's pretty much summed up by the documentation page introducing it here.
Iterating over a collection is uglier than it needs to be
So true..
The iterator is just clutter. Furthermore, it is an opportunity for error. The iterator variable occurs three times in each loop: that is two chances to get it wrong. The for-each construct gets rid of the clutter and the opportunity for error.
Exactly
When you see the colon (:) read it as “in.” The loop above reads as “for each TimerTask t in c.” As you can see, the for-each construct combines beautifully with generics. It preserves all of the type safety, while removing the remaining clutter. Because you don't have to declare the iterator, you don't have to provide a generic declaration for it. (The compiler does this for you behind your back, but you need not concern yourself with it.)
I'd like to sum it up more, but I think that page does it pretty much perfectly.
You can iterate over any collection that's Iterable and also arrays.
And the performance difference isn't anything you should be worried about at all.
Readability is important.
Prefer this
for (String s : listofStrings)
{
...
}
over
for (Iterator<String> iter = listofStrings.iterator(); iter.hasNext(); )
{
String s = iter.next();
...
}
Note that if you need to delete elements as you iterate, you need to use Iterator.
For example,
List<String> list = getMyListofStrings();
for (Iterator<String> iter = list.iterator(); iter.hasNext(); )
{
String s = iter.next();
if (someCondition) {
iter.remove();
}
}
You can't use for(String s : myList) to delete an element in the list.
Also note that when iterating through an array, foreach (or enhanced for) can be used only to obtain the elements, you can't modify the elements in the array.
For more info, see this.
Major drawback is the creation of an Iterator, which is not there with an index-based loop.
It is usually OK, but in performance-critical sections (in a real-time application for instance, when it has to run several hundreds times a second), it can cause major GC intervention...
A cleaner syntax !
There is no difference from the performance perspective as this is just a convenience for a programmer.
As others said, the enhanced for loop provides cleaner syntax, readable code and less type.
Plus, it avoids the possible 'index out of bound' error scenario too. For example, when you iterate a list manually, you might use the index variable in a wrong way, like:
for(int i=0; i<= list.size(); i++)
which will throw exception. But incase of enhanced for loop, we are leaving the iterating task to the compiler. It completely avoids the error case.
As others already answer, it is a syntax sugar for cleaner. If you compare to the class Iterator loop, you will found one less variable you will have to declare.
A foreach/enhanced for/for loop serves to provide a cursor onto a data object. This is particularly useful when you think in terms of “walk a file line by line” or “walk a result set record by record” as it is simple and straightforward to implement.
This also provides a more general and improved way of iterating compared to index-based methods because there is no longer any need for the caller (for loop) to know how values are fetched or collection sizes or other implementation details.
It is more concise. Only problem is null checking.
for (String str : strs) { // make sure strs is not null here
// Do whatever
}
Less typing! Plus more help from the compiler
The enhanced for-loop offers the following main advantage:
for (int i=0; i <= list.size(); i++)
It eliminates the repeated calculation of list.size() on every iteration in the non-enhanced version above. This is a performance advantage that matters.
Alternatively, you may calculate the size outside the loop as follows using an additional variable:
int size = list.size();
for (int i=0; i <= size; i++)
This question already has answers here:
How does the Java 'for each' loop work?
(29 answers)
Closed 7 years ago.
I wonder if there is a difference between these:
ArrayList<Example> list = new ArrayList<Example>
1-)
for(int i = 0; i < list.size(); i++) {
list.get(i).doSomething();
}
2-)
for(Example example : list) {
example.doSomething();
}
If there is not any difference which one is more common or efficient?
Traditional loop
for (int i = 0; i < list.size(); i++) {
list.get(i).doSomething();
}
allows to modify the list, e.g.:
you can add extra element at the end of list and it will be also iterated through
you know the index
can be used to refer to another list of the same size
can be used to refer to previous/next element
efficient only in RandomAccess lists
in case of LinkedList in every iteration of the loop, get(i) will have to iterate over all elements starting from head/tail to i
works only with List since List#get(int) is used
error prone, a lot of things that can go wrong, e.g.:
i = 0; instead of int i = 0; - will refer to variable declared before the loop, possible side effects outside of the loop
> instead of < - loop will not execute
j++ instead of i++ - infinite loop
.get(j) instead of .get(i) - will always get the same element
For-each loop
for (Example example : list) {
example.doSomething();
}
does not allow to modify the list
trying to do so will most likely result in ConcurrentModificationException
you don't know the index of the element
you cannot refer to previous/next element
efficient in all cases because uses Iterator specific for the collection
efficient in case of LinkedList
works not only with every Collection, but with every Iterable since Iterable#iterator() is used
you can easily replace List with a Set - no changes to the loop required
you can easily replace with your own class, it just has to implement Iterable
more robust (less code, fewer special characters)
Summary
for-each loop wins with a score 3 : 2.
The only reason to use a traditional loop is when:
the index of element is required, or
the list has to be modified
They are basically the same, but for-each (the second one) has certain restrictions.
It can be used for accessing the array elements but not for modifying them.
It is not usable for loops that must iterate over
multiple collections in parallel—for example, to compare the elements of two arrays.
It can be used only for a single element access and cannot be used to compare successive elements in an array. It is a forward-only iterator. If you want to access only a few elements of the array, you would need to use the traditional for loop.
The second one works with every type of (potentially unordered) Iterable, as it doesn't rely on random access, i.e. get(i).
for(:) statement is a read-only loop. You cannot change a collection within this loop. Also you cannot use more than one element.
The traditional for statement doesn't have such limits.
Excuse me if this has been asked before. My search did not bring up any other similar question. This is something that surprised me in Java.
Apparently, the enhanced for-loop only accepts an array or an instance of java.lang.Iterable. It does not accept a java.util.Iterator as a valid obj reference to iterate over. For example, Eclipse shows an error message for the following code. It says: "Can only iterate over an array or an instance of java.lang.Iterable"
Set<String> mySet = new HashSet<String>();
mySet.add("dummy");
mySet.add("test");
Iterator<String> strings = mySet.iterator();
for (String str : strings) {
// Process str value ...
}
Why would this be so? I want to know why the enhanced for-loop was designed to work this way. Although an Iterator is not a collection, it can be used to return one element at a time from a collection. Note that the only method in the java.lang.Iterable interface is Iterator<T> iterator() which returns an Iterator. Here, I am directly handing it an Iterator. I know that hasNext() and next() can be used but using the enhanced for-loop makes it look cleaner.
One thing I understand now is that I could use the enhanced for-loop directly over mySet. So I don't even need the extra call to get an Iterator. So, that would be the way to code this, and yes - it does make some sense.
The enhanced for loop was part of JSR 201. From that page, you can download the proposed final draft documents, which include a FAQ section directly addressing your question:
Appendix I. Design FAQ
Why can't I use the enhanced for statement with an Iterator (rather
than an Iterable or array)?
Two reasons: (1) The construct would not
provide much in the way on syntactic improvement if you had an
explicit iterator in your code, and (2) Execution of the loop would
have the "side effect" of advancing (and typically exhausting) the
iterator. In other words, the enhanced for statement provides a
simple, elegant, solution for the common case of iterating over a
collection or array, and does not attempt to address more complicated
cases, which are better addressed with the traditional for statement.
Why can't I use the enhanced for statement to:
remove elements as I traverse a collection ("filtering")?
simultaneously iterate over multiple collections or arrays?
modify the current slot in an array or list?
See Item 1 above. The expert group considered these cases, but
opted for a simple, clean extension that dose(sic) one thing well. The
design obeys the "80-20 rule" (it handles 80% of the cases with 20% of
the effort). If a case falls into the other 20%, you can always use an
explicit iterator or index as you've done in the past.
In other words, the committee chose to limit the scope of the proposal, and some features that one could imagine being part of the proposal didn't make the cut.
The enhanced for loop was introduced in Java 5 as a simpler way to
iterate through all the elements of a Collection [or an array].
http://www.cis.upenn.edu/~matuszek/General/JavaSyntax/enhanced-for-loops.html
An iterator is not a collection of elements,
it is an object that enables a programmer to traverse a container.
An iterator may be thought of as a type of pointer.
https://en.wikipedia.org/wiki/Iterator
So enhanced for loops work by going through all the elements in a structure that contains elements, while an iterator doesn't contain elements, it acts more like a pointer.
In your example, you are creating an iterator but not using it properly. As to answer your question of why the exception is being thrown- it's from the line:
for (String str : strings) {
"strings" is an iterator here, not a collection that you can iterate through. So you have a few options you can iterate through the set by using an enhanced for loop:
for(String myString : mySet){
//do work
}
or you can iterate through the set using an iterator:
Iterator<String> strings = mySet.iterator();
while(strings.hasNext()){
//do work
}
hope you find this helpful.
The error comes because you are trying to iterate over an Iterator, and not a List or Collection. If you want to use the Iterator, i recommend you to use it next() and hasNext() methods:
Set<String> mySet = new HashSet<String>();
mySet.add("dummy");
mySet.add("test");
Iterator<String> strings = mySet.iterator();
while(strings.hasNext()){
String temp = strings.next();
System.out.println(temp);
}
This question already has answers here:
Do we ever need to use Iterators on ArrayList?
(6 answers)
Closed 9 years ago.
I was reading the answer mentioned to the question
"Do we ever need to use Iterators on ArrayList?".
In the answer, the user stated something like this: "A big use case of iterators with ArrayLists is when you want to remove elements while iterating".
This could be achieved even using remove method of ArrayList in Java. My question is why we need iterator in ArrayList?
Consider the code:
import java.util.*;
public class ocajp66 {
public static void main(String[] args) {
ArrayList a = new ArrayList();
for (int i = 0; i < 10; i++) {
a.add(i);
}
System.out.printf("BEFORE ITERATOR\n");
for (int i = 0; i < a.size(); i++) {
System.out.printf("I:%d\n", a.get(i));
}
System.out.printf("AFTER ITERATOR\n");
Iterator i = a.iterator();
while (i.hasNext()) {
System.out.printf("I:%d\n", i.next());
}
}
}
Can anybody explain the significance of the iterator? It would be wonderful if you could explain me with code.
As you have stated iterator is used when you want to remove stuff whilst you iterate over the array contents. If you don't use an iterator but simply have a for loop and inside it use the remove method you will get exceptions because the contents of the array changes while you iterate through. e.g: you might think array size is 10 at the start of the for loop but it wont be the case once you remove stuff.. so when u reach the last loops probably there will be IndexOutofBoundsException etc.
It is clear that an ArrayList-like API could work without the iterator() method. However, an ArrayList is a Collection and the iterator() method is defined in the Collection interface ... so ArrayList has to implement it.
The point about deleting from an ArrayList is that doing it by indexing requires some thought:
for (int i = 0;
i < a.size(); // Hoist this at your peril
i++) {
if (a.get(i) == something) {
a.remove(i);
i--; // Leave this out at your peril
}
}
And it gets worse if you need to remove the list element in a method called from the loop ... 'cos the method has to then say that it has removed an element so that the caller can adjust the loop index.
A third reason why iterator is a good thing on an ArrayList is that it allows you to use Java 5's for (type var : iterable) ... syntax.
The bottom line is that you don't have to use iterators on ArrayList instances. If you don't want to, then don't.
This is an example of how it is possible to get the results you want in several different ways. This kind of redundancy is not unique to Java.
for (int i=0; i < myArray.length; i++) { ... }
This syntax was introduced in the very early versions of Java. It iterates over a usual Java array in a for { } loop. This is generally safe because Java arrays are fixed length and so "Index Out of Bounds" exceptions are not possible.
for (int i=0; i < myArrayList.size(); i++ { ... }
This syntax reflects a later release of Java, after the introduction of the Collections API which introduced ArrayList. Classes that implement the Collection interface, as already mentioned above, must implement an Iterator but you don't have to use it. This for { } loop doesn't, but the danger here is that ArrayLists are not fixed size. If it should shrink in the body of your for loop, and exception can result.
for (MyArrayType t : myArrayList) { }
This syntax was also released in a later release of Java. It is called the enhanced for loop. Any collection class that provides an Iterator by implementing the Iterable interface can take advantage of this syntax. This allows iterating over items in a collection without having to explicitly instantiate an Iterator. A favorite way to use this in a JavaFX Application is to loop through a bunch of controls to set a property to a value, eg. to reset the contents of a group of TextFields:
for (TextField tf : new TextField[] { txtf1, txtf2, txtf3, txtfa, txtfb, txtfc}) {
tf.setText("");
}
while (myCollectionIterator.hasNext()) { }
You can always explicitly instantiate an Iterator. This is safe to use when collection size is changing (from the Collection's own methods). It correct to say that the Iterator is more closely a property of the Iterable interface than a feature of the core Java language. But you can still use it as a language-like feature (in the enhanced for loop) thanks to later Java releases.
These constructs provide redundancy, but they are not identical. There are nuances of each that enable one to be particularly useful at a given time. You should use all of them.
Q: Why do we need an iterator in ArrayList?
We don't - just as you've shown in your code, you can iterate and do core operations on an ArrayList without an iterator. But it's a nice to have feature.
Q: Can anybody explain the significance of the iterator?
In addition to its design value, one I could see is its fail-fast feature. I quote this paragraph from the ArrayList documentation:
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException. Thus, in the face of concurrent
modification, the iterator fails quickly and cleanly, rather than
risking arbitrary, non-deterministic behavior at an undetermined time
in the future.
You were looking for code, you can actually see the ArrayList's iterator implementation here: ArrayList.java.
For your question, if we use list.remove() method instead of iterator.remove() then IndexOutOfBoundsException will be thrown.
list.remove() is safe to use if you put break statement once you find specific object/index to be removed so that it will be exited from the loop without any Exception(like IndexOutOfBoundsException )
Following iterator code still can throw ConcurrentModificationException if we use iterator EVEN in synchronized environment.
List<String> empNames = new ArrayList<String>();
synchronized (empNames) {
Iterator<String> iterator = empNames.iterator();
while (iterator.hasNext()) {
iterator.next();
empNames.add("Another Name"); // throws
// ConcurrentModificationException
}
}
I would like to know what are the advantages of Enhanced for loop and Iterators in Java +5 ?
The strengths and also the weaknesses are pretty well summarized in Stephen Colebourne (Joda-Time, JSR-310, etc) Enhanced for each loop iteration control proposal to extend it in Java 7:
FEATURE SUMMARY:
Extends the Java 5 for-each loop to allow access to the
loop index, whether this is the first
or last iteration, and to remove the
current item.
MAJOR ADVANTAGE
The for-each loop is almost certainly the most new
popular feature from Java 5. It works
because it increases the abstraction
level - instead of having to express
the low-level details of how to loop
around a list or array (with an index
or iterator), the developer simply
states that they want to loop and the
language takes care of the rest.
However, all the benefit is lost as
soon as the developer needs to access
the index or to remove an item.
The original Java 5 for each work took
a relatively conservative stance on a
number of issues aiming to tackle the
80% case. However, loops are such a
common form in coding that the
remaining 20% that was not tackled
represents a significant body of code.
The process of converting the loop
back from the for each to be index or
iterator based is painful. This is
because the old loop style if
significantly lower-level, is more
verbose and less clear. It is also
painful as most IDEs don't support
this kind of 'de-refactoring'.
MAJOR BENEFIT:
A common coding idiom is expressed at
a higher abstraction than at present.
This aids readability and clarity.
...
To sum up, the enhanced for loop offers a concise higher level syntax to loop over a list or array which improves clarity and readability. However, it misses some parts: allowing to access the index loop or to remove an item.
See also
Java 7 - For-each loop control access
Stephen Colebourne's original writeup
For me, it's clear, the main advantage is readability.
for(Integer i : list){
....
}
is clearly better than something like
for(int i=0; i < list.size(); ++i){
....
}
I think it's pretty much summed up by the documentation page introducing it here.
Iterating over a collection is uglier than it needs to be
So true..
The iterator is just clutter. Furthermore, it is an opportunity for error. The iterator variable occurs three times in each loop: that is two chances to get it wrong. The for-each construct gets rid of the clutter and the opportunity for error.
Exactly
When you see the colon (:) read it as “in.” The loop above reads as “for each TimerTask t in c.” As you can see, the for-each construct combines beautifully with generics. It preserves all of the type safety, while removing the remaining clutter. Because you don't have to declare the iterator, you don't have to provide a generic declaration for it. (The compiler does this for you behind your back, but you need not concern yourself with it.)
I'd like to sum it up more, but I think that page does it pretty much perfectly.
You can iterate over any collection that's Iterable and also arrays.
And the performance difference isn't anything you should be worried about at all.
Readability is important.
Prefer this
for (String s : listofStrings)
{
...
}
over
for (Iterator<String> iter = listofStrings.iterator(); iter.hasNext(); )
{
String s = iter.next();
...
}
Note that if you need to delete elements as you iterate, you need to use Iterator.
For example,
List<String> list = getMyListofStrings();
for (Iterator<String> iter = list.iterator(); iter.hasNext(); )
{
String s = iter.next();
if (someCondition) {
iter.remove();
}
}
You can't use for(String s : myList) to delete an element in the list.
Also note that when iterating through an array, foreach (or enhanced for) can be used only to obtain the elements, you can't modify the elements in the array.
For more info, see this.
Major drawback is the creation of an Iterator, which is not there with an index-based loop.
It is usually OK, but in performance-critical sections (in a real-time application for instance, when it has to run several hundreds times a second), it can cause major GC intervention...
A cleaner syntax !
There is no difference from the performance perspective as this is just a convenience for a programmer.
As others said, the enhanced for loop provides cleaner syntax, readable code and less type.
Plus, it avoids the possible 'index out of bound' error scenario too. For example, when you iterate a list manually, you might use the index variable in a wrong way, like:
for(int i=0; i<= list.size(); i++)
which will throw exception. But incase of enhanced for loop, we are leaving the iterating task to the compiler. It completely avoids the error case.
As others already answer, it is a syntax sugar for cleaner. If you compare to the class Iterator loop, you will found one less variable you will have to declare.
A foreach/enhanced for/for loop serves to provide a cursor onto a data object. This is particularly useful when you think in terms of “walk a file line by line” or “walk a result set record by record” as it is simple and straightforward to implement.
This also provides a more general and improved way of iterating compared to index-based methods because there is no longer any need for the caller (for loop) to know how values are fetched or collection sizes or other implementation details.
It is more concise. Only problem is null checking.
for (String str : strs) { // make sure strs is not null here
// Do whatever
}
Less typing! Plus more help from the compiler
The enhanced for-loop offers the following main advantage:
for (int i=0; i <= list.size(); i++)
It eliminates the repeated calculation of list.size() on every iteration in the non-enhanced version above. This is a performance advantage that matters.
Alternatively, you may calculate the size outside the loop as follows using an additional variable:
int size = list.size();
for (int i=0; i <= size; i++)