In Java you have several ways to iterate through a collection. This article is not about which one to choose but more about understanding which one does what. For those who are looking for an article telling them which one is the best : Stop searching and start coding! Pick the most elegant one depending on your situation.
Measuring Performance
I have developped a micro-benchmark to compare the different kind of iterations over a List. You can find the full source code on my github, but let’s have a look at the different method to iterate through a List.
//WHILE with iterator
int sum = 0;
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
sum += it.next();
}
// For with iterator
sum = 0;
for (Iterator<Integer> it = list.iterator(); it.hasNext();) {
sum += it.next();
}
//for each syntax
int sum = 0;
for (Integer i : list) {
sum += i;
}
//while increment
int sum = 0;
int i = 0;
while (i < list.size()) {
sum += list.get(i);
i++;
}
//for Increment
int sum = 0;
for (int i = 0; i < list.size(); i++) {
sum += list.get(i);
}
Let’s measure the performance of by iterating over a list and doing the sum of a list of 1000 integers. On my machine it gives :
Interpreting the benchmark results
The charts Y-Axis is in nano-seconds, so for the first chart, we can fairly say that all kind of iterations are similar. Even if we can notice that the two last scenarios are a bit faster.
The second chart shows that, for a LinkedList, the last two scenarios are way longer than the others.
If we look at the disassembled class files, available on my github, we can see that the firsts 3 scenarios are almost compiled to the same instructions (there is actually some very small differences that don’t affect the performances). All of them will call the iterator method of the List and then use the hasNext and next methods. The generated class file for the two lasts scenario are also almost identical. We can see that LinkedList is very bad at getting random elements with get(int) and in this case, it is better to use the iterator method.
Conclusion
Basically there is two strategy : using the fact that a collection implements Iterable or using some methods specific to the implementation (like get(int for a List)).
In my opinion, you should ALWAYS use the iterator method because :
- It can be used with all collections; If you want to change a
Listby aSet, you can! - All collections implementations have their own optimized version of the Iterator, it should always be the most (or near) efficient way to iterate through the collection
Then choosing between the while, for or for each version is just a matter of taste, it won’t change anything to the functionality.
Also if you need a loop counter you can do :
int sum = 0;
int i =0;
for (Iterator<Integer> it = list.iterator(); it.hasNext(); i++) {
sum += it.next();
}
For more details about the class files generated, I have posted a disassembled version of the class files on my github, next to the code.







If you feel the need to use increments for list iteration, at least see if your list implements RandomAccess. Sun introduced that so code can distinguish between LinkedList-like objects from ArrayList-like objects.
On the other hand, there is one application where you must use Iterator objects: deleting from lists. Never do:
for (int i = 0; i < list.size(); i++) {
if (shouldRemove(list.get(i))) {
list.remove(i);
}
}
Do
Iterator it = list.iterator();
while (it.hasNext()) {
if (shouldRemove(it.next())) {
it.remove();
}
}
The first will cause ConcurrentModificationExceptions and other logical errors.