Принятый ответ отвечает на вопрос, кроме исключительного случая ArrayList ...
Так как большинство разработчиков полагаются на ArrayList (по крайней мере, я так считаю)
Так что я обязан добавить правильный ответ здесь.
Прямо из документации разработчика: -
Улучшенный цикл for (также известный как цикл for-each) можно использовать для коллекций, которые реализуют интерфейс Iterable, и для массивов. В коллекциях выделяется итератор для выполнения интерфейсных вызовов hasNext () и next (). С ArrayList рукописный подсчитанный цикл примерно в 3 раза быстрее (с JIT или без него), но для других коллекций расширенный синтаксис цикла for будет в точности эквивалентен явному использованию итератора.
Существует несколько альтернатив для перебора массива:
static class Foo {
int mSplat;
}
Foo[] mArray = ...
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
zero () самый медленный, потому что JIT еще не может оптимизировать стоимость получения длины массива один раз для каждой итерации цикла.
one () быстрее. Он вытягивает все в локальные переменные, избегая поиска. Только длина массива обеспечивает выигрыш в производительности.
two () является самым быстрым для устройств без JIT и неотличимым от one () для устройств с JIT. Он использует расширенный синтаксис цикла for, представленный в версии 1.5 языка программирования Java.
Итак, по умолчанию вы должны использовать расширенный цикл for, но рассмотрите рукописный счетный цикл для критической итерации ArrayList.