Циклы в Java: синтаксис, примеры и выбор конструкции
Цикл for java удобен для диапазонов и индексов, а также повторяет код по условию. Foreach перебирает элементы последовательно, while повторяет тело до события, а do-while запускает его хотя бы один раз. В статье разберем циклы в java, примеры вывода и ошибки, которые мешают компиляции.
- Какие циклы есть в Java
- Цикл for в Java: синтаксис и порядок выполнения
- Цикл foreach в Java для массивов и коллекций
- Цикл while в Java
- Цикл do-while и обязательная первая итерация
- Вложенные циклы и двумерные данные
- break, continue и метки в Java
- Метод forEach и Stream API
- Ошибки в циклах Java
- Какой цикл выбрать для задачи
Какие циклы есть в Java
Java предлагает 4 основные конструкции: for, расширенный for (foreach), while и do-while. Выбирайте конструкцию по границе повторов, доступу к индексу и моменту проверки условия.
| Цикл | Синтаксис | Когда проверяется условие | Минимум итераций | Доступ к индексу | Типичная задача |
|---|---|---|---|---|---|
for | for (инициализация; условие; шаг) | До тела | 0 | Да, счетчик цикла служит индексом | Диапазон чисел или массив |
| foreach | for (Тип элемент : коллекция) | До тела | 0 | Встроенного индекса нет | Все элементы массива или коллекции |
while | while (условие) | До тела | 0 | Зависит от кода | Повтор до события |
do-while | do { ... } while (условие); | После тела | 1 | Зависит от кода | Меню или повторный ввод |
Для запуска примеров установите JDK с официальной страницы Java. Код удобно редактировать в IntelliJ IDEA Community или текстовом редакторе. Имя файла должно совпадать с именем public-класса.
Сохраните пример как ForOrder.java, выполните javac ForOrder.java, затем запустите java ForOrder. Правила конструкций описывает глава 14 JLS: разделы 14.12–14.14 посвящены циклам, 14.7 – меткам, 14.15–14.16 – break и continue.
Цикл for в Java: синтаксис и порядок выполнения
Цикл for java объединяет счетчик, проверку и изменение счетчика в одной строке. Он подходит, когда границы или шаг повторения известны заранее.
Три части заголовка
Java выполняет инициализацию один раз. Затем цикл проверяет условие, запускает тело и выполняет обновление счетчика.
public class ForOrder {
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
}
}
}Вывод:
1
2
3После обновления управление возвращается к условию. Если оно дает false, управление переходит к инструкции после цикла.
Область видимости счетчика
Счетчик, объявленный в заголовке, виден в условии, обновлении и теле цикла. После цикла имя недоступно, потому что область переменной закончилась.
public class ForScope {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println(i);
}
// System.out.println(i); // ошибка: cannot find symbol
}
}Закомментированная строка не мешает компиляции. Если убрать //, компилятор сообщит cannot find symbol. Когда значение нужно после цикла, объявите переменную заранее.
public class ForOutsideCounter {
public static void main(String[] args) {
int i;
for (i = 1; i <= 3; i++) {
System.out.println(i);
}
System.out.println("После цикла: " + i);
}
}Вывод:
1
2
3
После цикла: 4В заголовке цикла можно использовать var: такая форма доступна с Java 10 и требует начального значения.
for (var i = 0; i < 3; i++) {
System.out.println(i);
}Переменные, пропущенные части и шаг
Инициализация и обновление могут содержать несколько выражений одного типа. В условии остается одно логическое выражение.
public class ForParts {
public static void main(String[] args) {
for (int left = 1, right = 5; left <= right; left += 2, right++) {
System.out.println(left + " " + right);
}
}
}Вывод:
1 5
3 6
5 7
7 8
9 9Инициализацию и обновление можно вынести из заголовка, но точки с запятой сохраняются.
public class ForVariants {
public static void main(String[] args) {
int i = 3;
for (; i > 0;) {
System.out.println(i);
i--;
}
}
}Вывод:
3
2
1Для обратного отсчета уменьшайте счетчик. Шаг больше 1 задают через i += 2 или i -= 2. Конструкция for (;;) не проверяет условие и требует выхода через break, return или исключение.
public class ForStep {
public static void main(String[] args) {
for (int i = 10; i >= 0; i -= 2) {
System.out.print(i + " ");
}
}
}Вывод:
10 8 6 4 2 0 Метод System.out.println добавляет перевод строки, а System.out.print оставляет вывод в текущей строке. Пробел между числами в примере добавляет выражение i + " ".
Цикл foreach в Java для массивов и коллекций
Цикл foreach java записывают как for (Тип элемент : коллекция). В Java нет отдельного ключевого слова foreach: это разговорное название расширенного for. Конструкция работает с массивами и объектами Iterable.
Массив и ArrayList
Переменная цикла получает значение очередного элемента. Присваивание переменной не заменяет значение в массиве.
public class ForeachArray {
public static void main(String[] args) {
int[] numbers = {10, 20, 30};
for (int number : numbers) {
System.out.println(number);
}
}
}Вывод:
10
20
30Для изменения элементов используйте индексный for. Если массив хранит изменяемые объекты, вызов метода через переменную цикла может изменить состояние самого объекта.
public class ForeachList {
public static void main(String[] args) {
java.util.ArrayList<String> names = new java.util.ArrayList<>();
names.add("Анна");
names.add("Олег");
for (String name : names) {
System.out.println(name);
}
}
}Вывод:
Анна
ОлегИндексный обход и двумерный массив
Берите обычный for, когда нужен индекс, обратный проход или часть списка. У ArrayList метод size() возвращает размер, а get(i) получает элемент.
public class ForArrayList {
public static void main(String[] args) {
java.util.ArrayList<String> names = new java.util.ArrayList<>();
names.add("Анна");
names.add("Олег");
for (int i = 0; i < names.size(); i++) {
System.out.println(i + ": " + names.get(i));
}
}
}Вывод:
0: Анна
1: ОлегДвумерный массив хранит массивы строк. Внешний foreach получает строку, внутренний – ее элементы.
public class ForeachMatrix {
public static void main(String[] args) {
int[][] matrix = {{1, 2}, {3, 4}};
for (int[] row : matrix) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
}
}Вывод:
1 2
3 4 Удаление элемента во время foreach
Прямое удаление из ArrayList во время foreach нарушает работу итератора. При следующем обращении к нему обычно возникает ConcurrentModificationException.
Для удаления во время обхода используйте Iterator.remove().
public class IteratorRemove {
public static void main(String[] args) {
java.util.ArrayList<Integer> numbers = new java.util.ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
java.util.Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
if (iterator.next() % 2 == 0) {
iterator.remove();
}
}
System.out.println(numbers);
}
}Вывод:
[1, 3]Для удаления по условию подходит removeIf.
public class RemoveIfExample {
public static void main(String[] args) {
java.util.ArrayList<Integer> numbers = new java.util.ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.removeIf(number -> number % 2 == 0);
System.out.println(numbers);
}
}Вывод:
[1, 3]Цикл while в Java
while проверяет условие перед каждой итерацией. Если оно сразу ложно, тело не запускается. Используйте этот цикл, когда число повторов зависит от ввода или изменяемого состояния.
public class WhileDigits {
public static void main(String[] args) {
int number = 482;
int digits = 0;
while (number > 0) {
digits++;
number /= 10;
}
System.out.println(digits);
}
}Вывод:
3Каждая итерация удаляет последнюю цифру целочисленным делением на 10. Для числа 0 нужна отдельная обработка, потому что запись этого числа содержит одну цифру.
public class WhileInput {
public static void main(String[] args) {
java.util.Scanner scanner = new java.util.Scanner(System.in);
String text;
while (scanner.hasNextLine() && !(text = scanner.nextLine()).isEmpty()) {
System.out.println("Введено: " + text);
}
scanner.close();
}
}При вводе строк один, два и пустой строки вывод будет таким:
Введено: один
Введено: дваЦикл do-while и обязательная первая итерация
do-while сначала запускает тело, затем проверяет условие. Поэтому такая конструкция выполняется минимум 1 раз. После условия ставится точка с запятой.
public class DoWhileExample {
public static void main(String[] args) {
int choice = 0;
do {
System.out.println("Меню показано");
choice++;
} while (choice < 1);
}
}Вывод:
Меню показаноБерите do-while для меню или ввода, который нужно запросить хотя бы один раз. В отличие от while, эта конструкция выполняет тело до первой проверки.
Вложенные циклы и двумерные данные
Вложенный цикл запускается для каждой итерации внешнего. Если внешний цикл выполняется 3 раза, а внутренний – 4 раза, внутреннее тело сработает 12 раз.
public class MultiplicationTable {
public static void main(String[] args) {
for (int row = 1; row <= 2; row++) {
for (int column = 1; column <= 3; column++) {
System.out.print(row * column + " ");
}
System.out.println();
}
}
}Вывод:
1 2 3
2 4 6 Внутреннее тело выполняется 6 раз. Для прямоугольной матрицы число повторов равно произведению числа строк и столбцов. Если строки имеют разную длину, сложите количество элементов всех строк.
break, continue и метки в Java
Оператор break без метки завершает ближайший цикл. Оператор continue пропускает остаток текущей итерации и передает управление следующему повтору.
- В
forпослеcontinueвыполняется обновление счетчика. - В
whileуправление возвращается к проверке условия. - В
do-whileуправление переходит к проверке после тела. - В foreach цикл получает следующий элемент, если он существует.
public class BreakContinue {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
if (i == 2) {
continue;
}
if (i == 5) {
break;
}
System.out.print(i + " ");
}
}
}Вывод:
1 3 4 Метка перед внешним циклом позволяет выйти сразу из нескольких уровней.
public class LabeledBreak {
public static void main(String[] args) {
int[][] matrix = {{1, 2}, {3, 4}};
search:
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
if (matrix[row][column] == 3) {
System.out.println("Найдено");
break search;
}
}
}
}
}Вывод:
НайденоОператор break search завершает помеченный внешний цикл. Запись continue search продолжила бы внешний цикл с обновлением row++. Метки используйте только там, где без них вложенность трудно завершить.
Метод forEach и Stream API
Метод forEach выполняет действие для каждого элемента Iterable. Он доступен начиная с Java 8 и подходит для короткой операции без ручного счетчика.
public class ForEachMethod {
public static void main(String[] args) {
java.util.List<String> words = new java.util.ArrayList<>();
words.add("Java");
words.add("цикл");
words.forEach(word -> System.out.println(word));
}
}Вывод:
Java
циклДля диапазона чисел можно применить IntStream.range. Верхняя граница в диапазон не входит.
public class IntStreamExample {
public static void main(String[] args) {
java.util.stream.IntStream.range(1, 4)
.forEach(i -> System.out.print(i + " "));
}
}Вывод:
1 2 3 Обычный цикл проще, когда нужны break, continue или несколько связанных действий. Эти операторы нельзя применить из тела лямбды так же, как в обычном цикле.
Ошибки в циклах Java
Ошибки чаще всего появляются из-за неверной границы, неизменного счетчика или изменения коллекции во время обхода. Сначала найдите выражение, которое должно менять состояние программы.
Выход за границы массива
Индексы массива идут от 0 до length - 1. Условие i <= array.length допускает лишний индекс и вызывает ArrayIndexOutOfBoundsException.
public class ArrayBounds {
public static void main(String[] args) {
int[] numbers = {10, 20, 30};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
}
}Вывод:
10
20
30Используйте оператор < и поле length. Такая граница подходит массиву любого размера.
Бесконечный цикл и точка с запятой
Если while проверяет неизменный счетчик, условие остается истинным. Добавьте изменение счетчика на пути каждой обычной итерации.
public class InfiniteLoopFix {
public static void main(String[] args) {
int i = 0;
while (i < 3) {
System.out.println(i);
i++;
}
}
}Вывод:
0
1
2В обычном for обновление выполняется после continue. В while увеличение счетчика нужно разместить так, чтобы continue его не пропускал.
public class EmptyLoopBody {
public static void main(String[] args) {
for (int i = 0; i < 3; i++); {
System.out.println("Блок вне цикла");
}
}
}Вывод:
Блок вне циклаТочка с запятой завершает цикл с пустым телом. Уберите ее, если блок должен выполняться на каждой итерации.
Коллекция и сравнение double
Удаляйте элементы ArrayList через Iterator.remove() или removeIf. Прямое удаление списка внутри foreach может вызвать ConcurrentModificationException.
Не используйте точное равенство накопленного double как единственную границу. Целочисленный счетчик задает число шагов, а дробное значение вычисляется внутри.
public class DoubleLoopFix {
public static void main(String[] args) {
double value = 0.0;
for (int step = 0; step < 10; step++) {
value += 0.1;
}
System.out.println(value > 0.9);
}
}Вывод:
trueЦикл завершается по целому числу итераций. Для точных десятичных расчетов используйте BigDecimal.
Какой цикл выбрать для задачи
Сопоставьте задачу с границей повторов и данными. Такой выбор уменьшает число вспомогательных переменных и снижает риск ошибки индекса.
| Задача | Подходящий цикл | Причина |
|---|---|---|
| Повторить код для чисел от 0 до границы | for | Счетчик и шаг находятся в заголовке |
| Получить индекс или заменить элемент массива | for | Счетчик доступен в теле |
| Пройти все элементы массива или коллекции | foreach | Ручной индекс не нужен |
| Повторять до получения значения | while | Условие проверяется перед телом |
| Показать меню хотя бы один раз | do-while | Тело выполняется до проверки |
| Выполнить короткое действие для коллекции | forEach | Действие передается в лямбде |
Берите for для диапазона и индексов. Выбирайте foreach для последовательного чтения элементов. Используйте while при неизвестном числе повторов, а do-while – при обязательном первом запуске.
Совет от нашей редакции: сначала сформулируйте условие остановки словами, затем выберите цикл, который выражает его без лишнего состояния.
Популярное за неделю
- Как создать сайт самому в 2026: 4 способа + пошаговая инструкция 34 мин чтения
- Лучшие конструкторы для создания сайтов — плюсы, минусы и сравнения 22 мин чтения
- Как преобразовать строку в целое число в Java 2 мин чтения
- Метод tostring java: как получить читаемый вывод объектов 9 мин чтения
- Do while Java и цикл while: как работают и чем отличаются 4 мин чтения
- Как создать калькулятор на Java для Android с полным кодом 5 мин чтения
Комментарии