for/while. Классический способ: целочисленная переменная-индекс, которая увеличивается от 0 до
size(). Можно использовать для неполного обхода, с нестандартным шагом. Плата за это – возможность ошибиться в индексах и менее читабельный код.
Iterator. ООП-способ: методом
iterator() получить объект-итератор, и вызывать у него
next() пока
hasNext() возвращает
true. В реализации может быть дополнительная логика, такая как потокобезопасность. Такой «объект-итерацию» коллекции можно передать в сторонний код, не отдавая саму коллекцию. Всё еще требует слишком много кода.
for Iterable. Синтаксический сахар для обхода итератором. Простейший синтаксис когда нужен просто обход. В отличие от явного использования итератора не дает возможности
модифицировать элементы в процессе.
Стримы. Создать от коллекции стрим и работать с элементами в нём. Кроме простого
forEach(), можно воспользоваться всей мощью Java Steam API – фильтровать, преобразовывать и агрегировать элементы. За это создаются лишние объекты, а синтаксис гораздо более развесистый.
Функции Java 8. С этой версии появились удобные средства для обхода не только
строк. У коллекций и хэш-таблиц добавились методы
forEach для обхода и
replaceAll для модификации. Как со стримами, они дают функциональный стиль, но без избыточного создания стримов. Внутри используются простые итераторы и циклы
for.