Еще одним видом управляющих конструкций являются циклы. Циклы позволяют в зависимости от определенных условий выполнять определенное действие множество раз. В языке Java есть следующие виды циклов:
- for
- while
- do…while
Цикл for
Цикл for имеет следующее формальное определение:
1 2 3 4 |
for ([инициализация счетчика]; [условие]; [изменение счетчика]) { // действия } |
Рассмотрим стандартный цикл for:
1 2 3 |
for (int i = 1; i < 9; i++){ System.out.printf("Квадрат числа %d равен %d \n", i, i * i); } |
Первая часть объявления цикла — int i = 1
создает и инициализирует счетчик i. Счетчик необязательно должен представлять тип int
. Это может быть и любой другой числовой тип, например, float. Перед выполнением цикла значение счетчика будет равно 1. В данном случае это то же самое, что и объявление переменной.
Вторая часть — условие, при котором будет выполняться цикл. В данном случае цикл будет выполняться, пока i не достигнет 9.
И третья часть — приращение счетчика на единицу. Опять же нам необязательно увеличивать на единицу. Можно уменьшать: i--
.
В итоге блок цикла сработает 8 раз, пока значение i не станет равным 9. И каждый раз это значение будет увеличиваться на 1.
Нам необязательно указывать все условия при объявлении цикла. Например, мы можем написать так:
1 2 3 4 |
int i = 1; for (; ;){ System.out.printf("Квадрат числа %d равен %d \n", i, i * i); } |
Определение цикла осталось тем же, только теперь блоки в определении у нас пустые: for (; ;)
. Теперь нет инициализированной переменной-счетчика, нет условия, поэтому цикл будет работать вечно — бесконечный цикл.
Либо можно опустить ряд блоков:
1 2 3 4 5 |
int i = 1; for (; i<9;){ System.out.printf("Квадрат числа %d равен %d \n", i, i * i); i++; } |
Этот пример эквивалентен первому примеру: у нас также есть счетчик, только создан он вне цикла. У нас есть условие выполнения цикла. И есть приращение счетчика уже в самом блоке for.
Специальная версия цикла for
предназначена для перебора элементов в наборах элементов, например, в массивах и коллекциях. Она аналогична действию цикла foreach , который имеется в других языках программирования. Формальное ее объявление:
1 2 3 |
for (тип_данных название_переменной : контейнер){ // действия } |
Например:
1 2 3 4 5 |
int[] array = new int[] { 1, 2, 3, 4, 5 }; for (int i : array){ System.out.println(i); } |
В качестве контейнера в данном случае выступает массив данных типа int
. Затем объявляется переменная с типом int
То же самое можно было бы сделать и с помощью обычной версии for:
1 2 3 4 |
int[] array = new int[] { 1, 2, 3, 4, 5 }; for (int i = 0; i < array.length; i++){ System.out.println(array[i]); } |
В то же время эта версия цикла for более гибкая по сравнению for (int i : array)
. В частности, в этой версии мы можем изменять элементы:
1 2 3 4 5 |
int[] array = new int[] { 1, 2, 3, 4, 5 }; for (int i=0; i<array.length;i++){ array[i] = array[i] * 2; System.out.println(array[i]); } |
Перебор многомерных массивов в цикле
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int[][] nums = new int[][] { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; for (int i = 0; i < nums.length; i++){ for(int j=0; j < nums[i].length; j++){ System.out.printf("%d ", nums[i][j]); } System.out.println(); } |
Сначала создается цикл для перебора по строкам, а затем внутри первого цикла создается внутренний цикл для перебора по столбцам конкретной строки. Подобным образом можно перебрать и трехмерные массивы и наборы с большим количеством размерностей.
Цикл do
Цикл do сначала выполняет код цикла, а потом проверяет условие в инструкции while. И пока это условие истинно, цикл повторяется. Например:
1 2 3 4 5 6 |
int j = 7; do{ System.out.println(j); j--; } while (j > 0); |
В данном случае код цикла сработает 7 раз, пока j не окажется равным нулю. Важно отметить, что цикл do гарантирует хотя бы однократное выполнение действий, даже если условие в инструкции while не будет истинно. Так, мы можем написать:
1 2 3 4 5 6 |
int j = -1; do{ System.out.println(j); j--; } while (j > 0); |
Хотя переменная j изначально меньше 0, цикл все равно один раз выполнится.
Цикл while
Цикл while
сразу проверяет истинность некоторого условия, и если условие истинно, то код цикла выполняется:
1 2 3 4 5 6 |
int j = 6; while (j > 0){ System.out.println(j); j--; } |
Операторы continue и break
Иногда требуется выйти из цикла, не дожидаясь его завершения. В этом случае мы можем воспользоваться оператором break.
Например:
1 2 3 4 5 6 |
int[] nums = new int[] { 1, 2, 3, 4, 12, 9 }; for (int i = 0; i < nums.length; i++){ if (nums[i] > 10) break; System.out.println(nums[i]); } |
Так как в цикле идет проверка, больше ли элемент массива 10, то мы не увидим на консоли последние два элемента, так как когда nums[i] окажется больше 10 (то есть равно 12), сработает оператор break, и цикл завершится.
Правда, мы также не увидим и последнего элемента, который меньше 10. Теперь сделаем так, чтобы если число больше 10, цикл не завершался, а просто переходил к следующему элементу. Для этого используем оператор continue:
1 2 3 4 5 6 7 |
int[] nums = new int[] { 1, 2, 3, 4, 12, 9 }; for (int i = 0; i < nums.length; i++){ if (nums[i] > 10) continue; System.out.println(nums[i]); } |
В этом случае, когда выполнение цикла дойдет до числа 12, которое не удовлетворяет условию проверки, то программа просто пропустит это число и перейдет к следующему элементу массива.
Очень помогло, спасибо!