Циклы в Java: for, while, do-while, for-each
Виды циклов в Java
Цикл — это конструкция языка, которая многократно выполняет один и тот же фрагмент программы.
В Java четыре оператора цикла, и их удобно разделить на два типа: тип «пока» и тип «n раз».
Первый тип — «пока» — повторяет действие до тех пор, пока выполняется некоторое условие. Пример: увеличивать число на 5, пока оно не станет трёхзначным. Это циклы while и do-while:
while (boolexpr) { /*операторы*/ }
do { /*операторы*/ } while (boolexpr);
Второй тип — «n раз» — повторяет действия заранее известное количество раз. Пример: умножить число само на себя 4 раза. Это циклы for и for-each:
for (инициализация; условие; итерация) { /*операторы*/ }
for (тип итерационная_переменная : массив_или_коллекция) { /*операторы*/ }
Условие завершения должно быть очевидным, чтобы цикл не «сорвался» в бесконечный. Рассмотрим каждый из этих циклов.
Цикл while в Java
Цикл while — это цикл типа «пока». Он используется, когда фрагмент кода должен выполняться, пока истинно какое-то условие, а количество повторений заранее неизвестно.
После ключевого слова while в круглых скобках указывается выражение типа boolean — это условие цикла. Далее в фигурных скобках пишется тело цикла — код, который будет повторяться, пока условие возвращает true. В примере ниже, пока выполняется условие n > 0, будет вызываться System.out.println. Переменная n изменяется внутри тела цикла — именно это в конце концов позволяет из него выйти.
public class WhileExample1 {
public static void main(String[] args) {
int n = 10;
while (n > 0) {
System.out.println("Тик " + n--);
}
}
} Условие цикла while проверяется перед выполнением тела. Если при первой же проверке оно ложно, тело не выполнится ни разу. В этом главное отличие while от do-while.
Следующий пример показывает цикл while без тела. Даны два числа, 100 и 200, и нужно найти середину между ними. Значение i увеличивается на 1 на каждой итерации, а j уменьшается, пока они не станут равны. Изменение i и j происходит прямо в условии цикла, поэтому тело не нужно — вместо него ставится точка с запятой:
public class NoBodyExample {
public static void main(String[] args) {
int i = 100;
int j = 200; // найти середину между i и j
while (++i < --j) ; // цикл без тела
System.out.println("Середина: " + i);
}
} Цикл while применяется и для организации бесконечных циклов в виде while (true). Такой цикл сам никогда не завершится, поэтому внутри него должен быть оператор break (или return), иначе программа зависнет:
public class EndlessLoopExample {
public static void main(String[] args) {
int i = 0;
while (true) {
System.out.println(i++);
if (i == 5) {
break; // выход из бесконечного цикла
}
}
}
} Цикл do-while
Цикл do-while похож на while — это тоже цикл типа «пока», у него тоже есть тело и условие. Единственное отличие: условие записывается после тела и проверяется после его выполнения. Поэтому тело do-while выполнится хотя бы один раз, даже если условие сразу возвращает false.
Пример цикла do-while:
public class DoWhileExample {
public static void main(String[] args) {
int n = 10;
do {
System.out.println("Тик " + n--);
} while (n > 0);
}
} Классический сценарий для do-while — запрос данных у пользователя: значение нужно прочитать как минимум один раз, а затем повторять запрос, пока пользователь не введёт корректное значение.
Цикл for
Цикл for используется в Java, когда блок кода нужно выполнить несколько раз и количество повторений известно заранее.
Общая форма цикла for:
for (инициализация; условие; итерация) { /*операторы*/ } Пример цикла for:
public class ForTickExample {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("Тик " + i);
}
}
} В первом параметре (инициализация) обычно объявляют переменную, с помощью которой подсчитывается количество повторений цикла. Её называют счётчиком и чаще всего обозначают i. Счётчику задаётся начальное значение.
Во втором параметре (условие) указывают ограничение на счётчик — до какого значения он будет изменяться.
В третьем параметре (итерация) указывают выражение, изменяющее счётчик после каждого шага цикла. Обычно это инкремент или декремент, но подойдёт любое выражение, присваивающее счётчику новое значение. Изменять счётчик внутри тела цикла не рекомендуется — такой код сложнее читать и легче сломать.
Перед каждым шагом цикла (но после инициализации) проверяется условие. Если оно истинно, выполняется очередная итерация тела. Как и в while, тело может не выполниться ни разу, если условие ложно уже при первой проверке.
В первом и третьем параметрах можно через запятую указать несколько переменных и выражений:
public class ForExample {
public static void main(String[] args) {
for (int i = 1, j = 4; i < j; i++, j--) {
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
} Все три секции цикла for необязательны. Если опустить их все, получится ещё одна форма бесконечного цикла: for (;;) { }.
Цикл for-each
Цикл for-each (часто пишут слитно — foreach, или раздельно — for each; официальное название — «улучшенный for», enhanced for) — разновидность цикла for, появившаяся в Java 5. Он используется для последовательного перебора элементов массивов и коллекций (любых объектов, реализующих интерфейс Iterable). Его запись короче и безопаснее, чем у обычного for: невозможно ошибиться с границами индекса.
Общая форма:
for (тип итерационная_переменная : массив_или_коллекция) { /*операторы*/ } В следующем примере на каждой итерации переменной str автоматически присваивается значение очередного элемента массива args:
public class ForEachExample {
public static void main(String[] args) {
for (String str : args) {
System.out.println("Значение: " + str);
}
}
} Если нужно просто пройти по всем элементам массива или коллекции, выбирайте for-each — код получается короче и понятнее.
Важно
У for-each нет доступа к индексу элемента, а присваивание нового значения итерационной переменной не изменяет сам массив или коллекцию. Если нужно узнать позицию элемента, заменить элементы или обойти только часть массива — используйте обычный цикл for со счётчиком.
Операторы break и continue
Работой любого цикла можно управлять двумя операторами:
break— немедленно завершает цикл, выполнение продолжается со строки после него;continue— прерывает только текущую итерацию и переходит к следующей проверке условия.
public class BreakContinueExample {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // пропускаем чётные числа
}
if (i > 7) {
break; // выходим из цикла совсем
}
System.out.println(i); // выведет 1, 3, 5, 7
}
}
} Во вложенных циклах break и continue действуют только на тот цикл, внутри которого они непосредственно находятся. Чтобы выйти сразу из нескольких уровней, в Java используются метки (labeled break).
Какой цикл выбрать
| Цикл | Когда использовать | Проверка условия | Минимум итераций |
|---|---|---|---|
| while | Число повторений заранее неизвестно | Перед телом | 0 |
| do-while | Тело должно выполниться хотя бы раз (например, запрос ввода) | После тела | 1 |
| for | Число повторений известно, нужен счётчик или индекс | Перед телом | 0 |
| for-each | Перебор всех элементов массива или коллекции | Пока есть элементы | 0 |
Часто задаваемые вопросы
Чем цикл while отличается от do-while в Java?
while проверяет условие до выполнения тела, поэтому тело может не выполниться ни разу. do-while проверяет условие после тела, поэтому тело гарантированно выполнится хотя бы один раз, даже если условие сразу ложно.
Когда использовать for, а когда for-each (foreach)?
for-each подходит, когда нужно просто пройти по всем элементам массива или коллекции. Обычный for нужен, когда важен индекс элемента, требуется изменять элементы массива, идти с нестандартным шагом или обходить только часть элементов.
Как сделать бесконечный цикл в Java?
Два стандартных способа: while (true) { } и for (;;) { }. Чтобы программа не зависла, внутри такого цикла должен быть выход — оператор break или return, срабатывающий при определённом условии.
Можно ли изменить элементы массива в цикле for-each?
Нет. Итерационная переменная — это копия значения элемента (или копия ссылки), поэтому присваивание ей нового значения массив не меняет. Чтобы заменить элементы, используйте обычный for с обращением по индексу.
Видео объяснение
Предпочитаете видеоформат? Посмотрите этот урок с примерами и объяснениями.
Комментарии