Классический цикл for из трёх частей
Цикл for повторяет блок заданное число раз. Форма Java помещает в скобки три вещи, разделённые точкой с запятой:
Три части выполняются в строго определённом ритме:
- Инициализация (
int i = 0) — выполняется один раз, прежде всего остального. - Условие (
i < 5) — проверяется перед каждым проходом; цикл останавливается, когда оно ложно. - Обновление (
i++) — выполняется после каждого прохода, перед повторной проверкой условия.
Так что это выводит от i = 0 до i = 4. Счётчик i ограничен областью видимости цикла — он не существует после закрывающей фигурной скобки.
Счёт вверх, вниз и с шагом
Три части дают полный контроль над счётчиком:
i-- уменьшает, i += 5 прыгает шагами по пять. Условие определяет остановку с учётом направления: используйте > при счёте вниз и < или <= при счёте вверх.
Перебор массива
Счётный цикл естественно сочетается с массивом, используя .length как границу и i как индекс:
Обратите внимание, что colors.length — это поле без скобок: массивы в этом смысле особенные. А List, напротив, использует list.size(). Условие i < colors.length верно: индексы идут от 0 до length - 1, поэтому использование < (а не <=) предотвращает выход за границы.
Улучшенный цикл for-each
Когда вам нужен только сам элемент и никогда индекс, улучшенный for чище и в нём сложнее ошибиться — нет счётчика, на котором можно промахнуться на единицу:
Читайте for (String color : colors) как «для каждого color в colors». Это работает с массивами и со всем итерируемым. Цена: у вас нет индекса, и вы не можете добавлять или удалять элементы коллекции во время перебора (это выбрасывает ConcurrentModificationException). Берите счётный цикл, когда нужно любое из двух.
Вложенные циклы
Цикл внутри цикла — полезно для сеток, таблиц и пар. Внутренний цикл полностью отрабатывает на каждом проходе внешнего:
Это выводит сетку умножения 3x3. Давайте счётчикам осмысленные имена (row, col) вместо i, j, когда вложенность становится глубокой — это убережёт вас от путаницы, какой из них какой.
break и continue
break немедленно выходит из цикла. continue пропускает остаток текущего прохода и переходит к шагу обновления:
Это выводит 1 3 5 7. continue пропускает чётные; break завершает цикл, как только i превысит 7. Во вложенных циклах оба влияют только на самый внутренний цикл, если только вы не используете break с меткой.
Остерегайтесь бесконечных циклов
Если условие никогда не становится ложным, цикл выполняется вечно. Обычная причина — забыть обновление или двигать счётчик не в ту сторону:
for (int i = 0; i < 5; i--) { // i только уменьшается -> никогда не достигнет 5
System.out.println(i);
}
Намеренный бесконечный цикл опускает все три части — for (;;) { ... } — и полагается на break внутри, чтобы остановиться. Используйте это умеренно; while (true) обычно читается яснее.
Далее: циклы while
Цикл for хорош, когда счётчик известен заранее. Когда вы хотите повторять, пока не изменится какое-то условие — и у вас нет чёткого счётчика, — лучше подходит цикл while. Это следующая страница.
Часто задаваемые вопросы
Какой синтаксис у цикла for в Java?
Цикл for в Java состоит из трёх частей в скобках, разделённых точкой с запятой: for (инициализация; условие; обновление) { ... }. Например, for (int i = 0; i < 5; i++) { ... } начинает i с 0, выполняет тело, пока i < 5, и прибавляет 1 к i после каждого прохода. Все три части необязательны.
В чём разница между циклом for и циклом for-each в Java?
Классический цикл for использует явный счётчик, поэтому вы управляете индексом и направлением — лучше всего, когда нужен индекс или вы хотите пропускать элементы. Улучшенный цикл for-each, for (Тип элемент : коллекция), проходит по всем элементам по порядку без индекса — чище, когда вам нужен только сам элемент и никогда позиция. for-each не может менять структуру коллекции во время перебора.
Как перебрать массив в Java?
Либо обращайтесь к нему по индексу в счётном цикле — for (int i = 0; i < arr.length; i++) { использовать arr[i]; } — либо, когда индекс не нужен, используйте for-each: for (int x : arr) { использовать x; }. Массивы дают свой размер через поле .length (без скобок), а списки используют .size().