When to use for (int i =0; ; ) / for-each / iterator to go through a List
Is it a matter of preference to use the traditi开发者_C百科onal for loop, the for-each loop or an iterator to go through a List?
1) for(MyClass mc : al){ // do something on mc }
or
2) iter = arrayList.iterator();
while(iter.hasNext()){MyClass mc = iter.Next()}
For most iterations you should use the regular loop:
for (Object o : list) { /* */ }
It is much more readable, intent is clear, and potential bugs are kept to a minimum.
Use an iterator when you need explicit control over the iteration, for example, when you might want to start iteration all over again.
You can use iterators to avoid ConcurrentModificationExceptions.
iter = arrayList.iterator();
while(iter.hasNext()) {
MyClass mc = iter.next();
if(shouldItBeRemoved(mc)) {
iter.remove(); // Will not throw ConcurrentModificationException
// arrayList.remove(mc); // Will throw CME
}
}
That said, I find the for-each loop more readable, so use it whenever you do not modify the list in the loop.
My preference is
1) If I need to move forward through the list without any modification to the List object, for readable and clean code, I will use:
for(MyClass mc : list){
/* code without modification to list */
}
2) If I need modification to the List object, no doubt I will use:
iter = list.iterator();
while(iter.hasNext()) {
MyClass mc = iter.next()
/* code without modification to list */
/* code with modification to list */
}
Additional Information:
Iterator will be useful if you need to create a utility method that can traverse multiple type of collection (e.g. ArrayList, LinkedList, HashSet, TreeSet, LinkedHashSet)
public class Example {
public static void iterateAndDoSomething(Iterator<MyClass> iter) {
while(iter.hasNext()) {
MyClass mc = iter.next();
/* code without modification to list */
/* code with modification to list */
}
}
public static void main(String[] args) {
ArrayList<MyClass> als = new ArrayList<MyClass>();
TreeSet<MyClass> tss = new TreeSet<MyClass>();
iterateAndDoSomething(als.iterator());
iterateAndDoSomething(tss.iterator());
}
}
Some classes doesn't have iterator()
method (such as NodeList
) then you have to use #1. Other than that, it's a matter of preference I think.
I use for (i=0;
if i need the index during the loop, an iterator()
if it's the only thing possible or I need to remove()
elements (concurrently). For all other cases I use the shortened for loop for(MyClass mc : al)
because of its readability.
Traditional loops (indexed based) are useful where you need the index to manipulate the array.
If you don't care about the indexes and you interest is only getting the value out of the array, for..each loop is the best fit.
Some Collection objects doesn't provide a way to get the values using index, in that case iterator() is the only option.
Based on the code snippet you provided, it should be obvious that for-each like iteration produces cleaner code.
With the presence of both, you do have the flexibility on what you would like to choose.
The for-each-loop isn't available on Java 1.4, so this might be eliminated if you need to support Java <1.5.
The other two choices are a matter of use case and style I think. Iterators usually look cleaner, but you might also need to have a counter variable, so a for-loop might fit your needs better. Additionally some list implementations do not provide iterators, so you will have to use an index.
I have read that iterators are very helpful in Swing especially if you iterate through collection in paintComponent(Graphics g)
method.
The benefit of iterators is that you can iterate through the same collection from multiple threads and you even remove an element of that collection using the method remove()
while the collection is accessed concurrently elsewhere.
The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. THIS means that if you modify the same collection concurrently then behavior of method remove is not defined. BUT method remove works well EVEN IF you traverse through the same collection concurrently while calling iterator.remove()!!! I have used this in my GUI.
According to my experience it is necessary to use an iterator in the method paintComponent
rather than cycle for
or for-each
!
精彩评论