Циклы – это важный элемент программирования, который позволяет выполнять один и тот же участок кода многократно. Иногда цикл не завершается до тех пор, пока выполняется определённое условие. В Java существует несколько видов циклов, включая цикл for, foreach, while и do-while. Давайте подробно обсудим каждый из них и рассмотрим их применение с помощью примеров кода.
Словарь циклов
Сперва познакомимся со словами, которыми оперируют программисты, говоря о циклах. В их число входят следующие:
- Тело цикла (Loop Body): Часть кода внутри цикла, которая выполняется многократно,
- Итерация (Iteration): Один круг выполнения кода в цикле. Каждая итерация представляет собой один “поворот” цикла,
- Условие цикла (Loop Condition): Проверка, которая говорит циклу, должен ли он продолжать выполняться или завершиться,
- Инициализация цикла (Loop Initialization): Начальное установление значений, которые цикл будет использовать перед началом,
- Счётчик (Counter): Переменная, которая отслеживает количество итераций, обычно увеличиваясь после каждой итерации,
- Инкремент (Increment): Действие, которое увеличивает значение переменной-счётчика (например, добавление 1 к текущему значению),
- Индекс (Index): Числовая переменная, которая используется для доступа к элементам списка или коллекции в цикле.
Вообще говоря, можно расписать алгоритм “полить огород”: тело цикла – полить грядку, итерация – очередное выполнение тела цикла (поливание очередной грядки), условие цикла – пока количество политых грядок меньше количества всех грядок в огороде, инициализация цикла – начинаем с самой близкой к калитке грядки и число политых грядок устанавливаем в 0, счётчик – переменная, считающая количество политых грядок, инкремент – операция, увеличивающая счётчик на 1 после каждой политой грядки, индекс – порядковый номер поливаемой грядки.
For
Цикл for используется, когда известно количество итераций, которые нужно выполнить. В Java он имеет следующий синтаксис:
1 2 3 |
for (инициализация; условие; инкремент) { // Код, который будет выполняться в цикле } |
Термины инициализация, условие, инкремент вам уже знакомы. Ещё раз уточним про них:
- инициализация – выполняется только один раз в начале цикла и инициализирует переменные.
- условие – это логическое условие, которое проверяется перед каждой итерацией. Если оно ложно, цикл завершается.
- инкремент – этот блок кода выполняется после каждой итерации и обновляет переменные.
Для начала напишем простой пример, позволяющий выводить несколько чисел по порядку. У программистов так заведено, что переменная-счётчик носит величественное имя i – как iterator.
1 2 3 4 5 6 7 8 9 |
public class FirstProject { public static void main(String[] args) { int iterationCount = 10; for (int i = 1; i <= iterationCount; i++) { System.out.println("Итерация №" + i); } } } |
Разве это не великолепно? Мы написали всего одну строку с выводом текста, а вывелось целых десять. И превратить десять в двадцать, тридцать, а то и сто, можно лёгким движением руки. Подумать только, вот что такое циклы! Делать можно вещи и куда более интересные. Можно, например, выводить каждое второе, третье, четвёртое число, или рассчитывать числа Фибоначчи, или узнать факториал введённого числа, или, или, или…
Попробуем использовать цикл в совокупности с массивом. Как правило, именно такая синергия чаще всего встречается в программах. У массивов есть свойство length, которое позволяет узнать количество их элементов. Напишем программу, которая создаёт массив из нескольких футбольных клубов. После этого она будет все их названия переводить в верхний регистр в первом цикле. Напоследок во втором цикле будет осуществляться вывод на консоль с указанием порядкового номера клуба.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class FirstProject { public static void main(String[] args) { String[] footballClubs = { "Арсенал", "Ливерпуль", "Манчестер Сити", "Манчестер Юнайтед", "Челси", "Ньюкасл Юнайтед", "Тоттенхэм" }; for (int i = 0; i < footballClubs.length; i++) { footballClubs[i] = footballClubs[i].toUpperCase(); } for (int i = 0; i < footballClubs.length; i++) { int numberOfIteration = i + 1; System.out.println("Клуб №" + numberOfIteration + ": " + footballClubs[i]); } } } |
Итак, английские клубы выведены в верхнем регистре, для каждого из них указан порядковый номер. Красиво.
Foreach
Цикл foreach используется для прохождения по элементам массивов или коллекций. В прошлом примере с помощью цикла for мы тоже прошли массив. Однако нам для этого понадобилась переменная-счётчик i, которая позволяла получать индексы элементов массива поочерёдно. Здесь же такая не пригодится. Цикл foreach имеет следующий синтаксис:
1 2 3 |
for (Тип_элемента имя_элемента: коллекция) { // Код, который будет выполняться в цикле } |
Сделаем цикл, опять же, выводящий названия футбольных клубов в верхнем регистре. Нюанс заключается в том, что переменной-счётчика нет. Придётся либо не указывать порядковый номер клуба, либо же завести отдельную переменную для этих целей.
1 2 3 4 5 6 7 8 9 10 |
public class FirstProject { public static void main(String[] args) { String[] footballClubs = { "Арсенал", "Ливерпуль", "Манчестер Сити", "Манчестер Юнайтед", "Челси", "Ньюкасл Юнайтед", "Тоттенхэм" }; for (String club : footballClubs) { System.out.println("Клуб: " + club.toUpperCase()); } } } |
Как видно, переменной для хранения порядкового номера клуба у нас нет. Поэтому вывести его мы не можем. Всё зависит от преследуемых вами целей.
While – сначала подумай, потом сделай
В отличие от for и foreach, которые используются, когда заранее известно, сколько итераций должно быть произведено, while, впрочем, как и do-while, в основном зовут помочь в ситуациях, где количество повторений непонятно. Яркий пример – когда прекращение выполнения цикла регулируется желанием пользователя – этого мы точно предсказать не можем.
While предполагает, что итераций может быть как 0, так и 1, 2 и так далее. То есть, если условие неверно, то может не произойти ни одного повторения. While сначала проверяет условие, а потом делает – если условие верно.
Напишем программу, которая запросит у пользователя начальное значение, множитель, на который это начальное значение будет каждую итерацию домножаться, и верхнюю границу – при достижении которой цикл завершится. Если число сразу будет выше верхней границы, цикл не проведёт ни одной итерации.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.util.Scanner; public class FirstProject { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Введите начальное число -> "); double startNum = scanner.nextDouble(); System.out.print("Введите множитель -> "); double multiplier = scanner.nextDouble(); System.out.print("Введите верхнюю границу -> "); double topBorder = scanner.nextDouble(); double currentNum = startNum; while (currentNum < topBorder) { currentNum *= multiplier; System.out.println("Текущее значение: " + currentNum); } System.out.println("Верхняя граница пересечена, цикл завершён"); } } |
Если начальное число меньше верхней границы, цикл начинает проводить свои манипуляции. Однако если условие сразу неверно, то не проходит ни одна итерация, ведь граница уже пересечена.
Do-while – сначала сделай, потом подумай
Цикл do-while, так же, как и while, используется в основном в ситуациях, где заранее количество итераций предусмотреть сложно или невозможно. В отличие от while, цикл do-while обязательно выполнит хотя бы одну итерацию, даже если условие сразу же не выполняется. Он может произвести 1, 2 и так далее повторений. Do-while сначала делает, и только потом проверяет условие. Если условие оказалось неверным, то итерация так и остаётся одна, а цикл завершается.
Для примера используем программу, которая на каждой итерации будет спрашивать пользователя, не хочет ли он выйти из программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import java.util.Scanner; public class FirstProject { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Добро пожаловать в программу!"); int answer; do { System.out.println("---МЕНЮ---"); System.out.println("* напишите код пункта *"); System.out.println("1 - сложить числа"); System.out.println("2 - умножить числа"); System.out.println("0 - выход =("); answer = scanner.nextInt(); if (answer == 1 || answer == 2) { System.out.print("Введите первое число -> "); int firstNum = scanner.nextInt(); System.out.print("Введите второе число -> "); int secondNum = scanner.nextInt(); if (answer == 1) { int sum = firstNum + secondNum; System.out.println("Сумма чисел = " + sum); } else { int mul = firstNum * secondNum; System.out.println("Произведение чисел = " + mul); } } else if (answer != 0) { System.out.println("???"); } } while (answer != 0); System.out.println("Цикл завершён, но вы возвращайтесь"); } } |
Программа каждый раз заботливо выводит меню для пользователя, чтобы он не забыл, какое число за что отвечает. Более того: ещё до того, как пользователь что-либо введёт, программа всё равно выведет меню. Это и есть та самая первая итерация, которая выполняется в любом случае. А после неё пользователь уже сам волен решать – выходить ему из программы или же поскладывать числа.
Если пользователь вводит число “5”, программа выводит символы непонимания. Если была введена единица, программа исправно считает сумму, если двойка – произведение. И так может продолжаться вечно, ровно до тех пор, пока пользователь не нажмёт 0. Заранее предугадать, сколько итераций случится, пока пользователю не надоест, сложно. Поэтому мы используем не for и не foreach, в которых это нужно знать перед началом цикла. Также нужно провести одну итерацию в любом случае. Потому мы используем именно do-while, а не обычный while.
Теперь вы знакомы с основами циклов в Java и можете применять их в своих программах. Циклы позволяют повторно выполнять действия. Это делает программу более гибкой и позволяет избежать повторения однотипных кусков кода. За счёт этого код становится гораздо более читаемым.
Уведомление: Как делать запросы к API на Java с ПК