Бесплатная миграция IT-инфраструктуры в облако

Циклы в Java: основы работы, как использовать и примеры

Альберт Гильмутдинов
Альберт Гильмутдинов
Технический писатель
10 апреля 2023 г.
5643
17 минут чтения
Средний рейтинг статьи: 2.9

Новички в программировании начинают с изучения синтаксиса языка, чтобы оттачивать навыки на практике. А опытный IT-специалист — это тот, кто уже знаком с алгоритмами и структурами данных. Обе группы рано или поздно сталкиваются с особенностями языка.

Мы опишем работу операторов с условиями и затронем виды циклов в Java:

  • While
  • For
  • For Each
  • Do While

Инструкция пригодится начинающим и опытным IT-специалистам, которые хотят узнать, как организован синтаксис.

Для чего они нужны

Начнем с аналогий. Жизнь человека полностью состоит из последовательности действий. Они меняются в зависимости от внешних и внутренних условий. Например, действие «Сегодня пойду на тренировку» содержит условия. 

Один человек не придет в зал, если у него болит горло, для другого спорт — это непрерывная карьера, где недомогание и настроение — несущественные факторы для отказа от силовой нагрузки. 

То же самое относится и к приложениям. В коде содержатся специальные условия. Они настраивают работу ПО, в зависимости от идеи разработчика. 

Итерация цикла в Java — это однократное выполнение тела цикла, пока условия выхода из цикла не соблюдены. Такие алгоритмы создают функциональность утилиты. Они описывают модель повторяющихся действий и содержат в себе информацию о количестве повторений.

Решим задачу — пропишем числа от 1 до 150 обычным перечислением:

public class Main {
   public static void main(String[] args) {
       System.out.println(1);
       System.out.println(2);
…(повторы)
       System.out.println(150);
   }
}

Получили требуемый результат — необходимый диапазон чисел. Такой подход неудобен — приходится вручную описывать каждое повторяющееся действие, хотя между каждым повторением есть связь с предыдущим (кроме первого).

Проще описать алгоритм, где мы поместим две строчки и получим аналогичный результат. Усложним задачу — цифры должны печататься через пробел:

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i <= 150; i++) {
            System.out.print(i + " ");
        }
    }
}

Вывели цифры и отделили их пробелом. Изначально мы бы описывали каждый оператор печати. Небольшой лайфхак — фигурные скобки тела цикла допустимо стереть, если в цикле содержится одна строчка. 

Как создать цикл в Java по примеру:

  1. Создать (инициализировать) переменную. Определили i и присвоили ей единицу, так как отсчет у нас начинается с нее.
  2. Добавить условие выхода.. Обозначили, при каких условиях число выводится после запуска кода. Символ <= означает «меньше, либо равно». По условию задачи необходимо добавить все цифры в диапазоне, включая 150. Можно применить «меньше» + 1, то есть 151. 
  3. Условие инкремента. Что произойдет, когда цифра будет меньше либо равна 15. Мы будем увеличивать число на 1 на каждой итерации цикла. Алгоритм повторяется, пока значение проверки условия равно булеву выражению «Истина». Когда при очередной итерации появляется «Ложь» — тело цикла не выполняется, он заканчивается, и выполнение кода переходит к следующей части программы.

Так работают операторы цикла For в Java. Разберем особенности разных типов циклов в Java. 

Цикл

Для чего нужен

While

Повторение фрагмента неопределенное количество раз, в т.ч. и 0

For

Повторение кода в заданном числе итераций, в т. ч. и 0

For Each

Перебор элементов массива

Do While

Повторение фрагмента с проверкой после итерации как минимум один раз

While

Это оператор цикла с неизвестным заранее числом итераций. Он выполняет заданный шаблон, пока условие выражения не примет ложь и буквально означает «пока». 

Аналог из жизни — учеба в университете продолжается, пока студент не пройдет весь обучающий курс, не сдаст все промежуточные и итоговые экзамены. Алгоритм действий включает в себя: посещение лекций, подготовку к контрольным этапам проверки знаний. 

while (Условия) {
 // Тело алгоритма
}

Условие, которое находится внутри оператора While, принимает булево значение. Оно только истинно или ложно. Алгоритм срабатывает, пока выражение принимает True (Правду). 

Во всех остальных случаях фрагмент кода внутри тела цикла не выполняется.

Применим While и увидим на практике итог при True и как тело цикла перестанет выполняться через пять итераций. Пример цикла с параметром в Java:

public class Main {
    public static void main(String[] args) {
        int count = 0;
        while (count < 5) {
            System.out.println("Число: " + count);
            count++;
        }
        System.out.println("Завершено. При проверке игнорируется фрагмент и последовательно выполняется остальная часть программы");
    }
}

Java соответствует всем принципам объектно-ориентированной методологии и базируется строго на них. Чтобы успешно запустить код, объявляем класс Main и одноименный метод после public static void main(String[] args). Перед while инициализировали необходимую для условия цикла переменную.

Пока число меньше 5, печатается строка и текущее значение переменной count. Затем count увеличивается на 1 (инкрементируется). Результат:

Число: 0
Число: 1
Число: 2
Число: 3
Число: 4
Завершено. При проверке игнорируется фрагмент и последовательно выполняется остальная часть программы

For

While лучше применять в том случае, когда изначально неизвестно количество итераций. C For все обстоит иначе — его применяют, когда число вхождений известно изначально, для многократного повтора фрагмента кода. 

В For можно создать переменную и сразу прописать условия. Обычно он нужен тогда, когда нет пользовательского ввода. Но рассмотрим одну интересную задачу:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введите число для вычисления его факториала: ");
        int num = scanner.nextInt();
        BigInteger factorial = BigInteger.ONE;
        for (int i = 1; i <= num; i++) {
            factorial = factorial.multiply(BigInteger.valueOf(i));
        }
        System.out.println("Факториал числа " + num + " равен " + factorial);
    }
}

Мы узнаем количество повторений еще до цикла. Число зависит от фиксировано заданного пользователем количества умножений от 0 до n (где n — любое вводное по формуле 1*2*3..*n) через математическую функцию. 

BigInteger.valueOf(i) создает новый объект BigInteger, который представляет i. factorial.multiply(BigInteger.valueOf(i)) умножает текущее значение factorial (которое также является объектом BigInteger) на объект BigInteger. Присвоение factorial = ... устанавливает значение factorial в новый объект BigInteger, представляющий произведение.

На каждой итерации цикла умножается текущее значение factorial на i, а результат сохраняется обратно в factorial. К концу цикла выводим факториал числа.

Покажем разницу с While:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int numberToGuess = 498;
        int guess = 0;

        while (guess != numberToGuess) {
            System.out.print("Угадай число (от 1 до 1000): ");
            guess = scanner.nextInt();

            if (guess < numberToGuess) {
                System.out.println("Меньше");
            } else if (guess > numberToGuess) {
                System.out.println("Больше");
            }
        }

        System.out.println("Вы выиграли, это правильный ответ: " + numberToGuess + "!");
    }
}

Здесь применяем While, так как повторения полностью зависят от того, сколько раз юзер введет значение. Но мы должны остановиться, когда он напечатает 498. Только в таком случае можно выйти из цикла. 

For Each

Это приспособленный для удобной итерации по итерируемым объектам (массивам и коллекциям) вариант цикла for. Он появился в Java 5.0 в 2004 году и упрощает написание кода. 

Как работает цикл с условием в Java:

public class Main {
    public static void main(String[] args) {
        int[] numbers = {145, 342, 2343, 423, 23, 96, 11, 20, 590, 1457};


        // Выведем только четные числа
        for (int number : numbers) {
            if (number % 3 == 0) {
                System.out.print(number + " ");
            }
        }
    }
}

Результат:

342 2343 423 96 

Применяем цикл For Each для выборочного вывода только определенных элементов из массива на основе определенных условий. 

Выводим числа кратные трем. Здесь видно, как For Each применяется для выполнения операций над коллекциями в Java. Через него можно перебирать элементы массива. 

Do While

Основное различие от while — do-while выполняет первую итерацию еще до проверки условия цикла. While может вообще не выполнить часть программы, если результат проверки принимает ложное значение. 

Запись цикла в Java с Do-While выглядит так:

do {
    // Фрагмент кода
} while (условие);

Условие сверяется по завершении итерации.

Вот шаблон, иллюстрирующий разницу между do-while и while:

public class Main {
    public static void main(String[] args) {
        // пример do-while
        int count1 = 0;
        do {
            System.out.println(count1);
            count1++;
        } while (count1 < 5);

        // пример while
        int count2 = 0;
        while (count2 < 5) {
            System.out.println(count2);
            count2++;
        }
    }
}

Применили do-while. Алгоритм всегда выполнит первое вхождение, а далее сверится с поставленным условием (но только в конце итерации). 

Код внутри оператора do выполняется минимум один раз. Даже если бы мы начали с числа 5. Цикл завершится, когда юзер выполнит наш запрос, и буквально означает «Сделай это действие, позже проверь, соблюдается ли заданное правило».

Во второй части примера ничего не произойдет, если мы присвоим count2 5. Код внутри оператора while выполняется строго при соблюдении условия, которое мы вписали в алгоритм. 

В целом, do-while нужен, когда необходимо выполнить фрагмент минимум единожды. While нужен тогда, когда лучше применить блок кода только при булевом выражении «True».

Операторы

С помощью специальных конструкций можно вмешиваться в работу цикла. Например, допустимо прерывать их, возвращать значение в функцию или исключать нежелательный результат. 

Оператор

Для чего нужен

Что делает

Break

Прерывает выполнение цикла

Выходит из фрагмента кода. Продолжает работу с оператора, который следует после него

Continue

Пропускает указанную итерацию в цикле

Игнорирует вхождение и начинает следующее

Return

Возврат значения функции

Выходит из всей функции и возвращает указанные данные внутри оператора, если их указал разработчик 

Break

Это оператор перехода, который завершает цикл или switch. Он преждевременно прекращает итерацию, если соблюдены условия Break. В памяти сохраняется итог вычислений из предыдущего вхождения. 

Пример в Java с циклом, код:

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            if (i == 5) {
                break;
            }
            System.out.println(i);
        }
    }
}

Фрагмент кода использует цикл от 1 до 10. На каждой итерации мы проверяем, равно ли число 5.

Если это так, то цикл завершается оператором break, исключая оставшиеся 5 итераций. Следовательно, выводятся только числа от 1 до 4.

Итоговое значение — это 4, последний результат игнорируется компилятором. Принцип работает во всех типах циклов в Java. На практике Break применяется, когда нужно исключить возможный результат или вхождение. Он также подходит для повышения производительности.

Continue

Оператор не прерывает цикл, а выборочно исключает возможные итерации. При запуске оператора итерация завершается, и программа начинает проверку условия заново. В памяти сохраняется итог предыдущих вычислений. 

Вот реализация проекта через continue:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Map<String, Double> assortment = new HashMap<>();
        assortment.put("Яблоко", 9.5);
        assortment.put("Банан", 15.5);
        assortment.put("Апельсин", 18.0);
        assortment.put("Виноград", 40.0);
        assortment.put("Ананас", 89.0);

        System.out.println("Добро пожаловать в интернет-магазин! Наш ассортимент:");
        System.out.println(assortment);

        double totalAmount = 0.0;
        boolean moreItems = true;
        while (moreItems) {
            System.out.println("Напишите название товара для покупки (или 'выйти'):");
            String itemName = input.nextLine();

         if (itemName.equals("выйти")) {
                moreItems = false;
                continue;
            }

            if (!assortment.containsKey(itemName)) {
                System.out.println("Извините, у нас нет этого предмета в ассортименте.");
                continue;
            }

            System.out.println("Напишите сколько нужно товара, " + itemName + " который вы хотели бы купить:");
            int quantity = input.nextInt();
            input.nextLine(); // очищаем буфер

            double itemPrice = assortment.get(itemName);
            double itemTotal = itemPrice * quantity;

            System.out.println("Вы добавили " + quantity + " " + itemName + " в корзину. Общая цена: " + itemTotal);

            totalAmount += itemTotal;
        }

        System.out.println("Спасибо за покупки! К оплате: " + totalAmount);
    }
}

Эта упрощенный интернет-магазин. Через него можно выбирать продуктовый набор из определенного ассортимента и рассчитывать общую стоимость заказа.

В начале программы создается HashMap для хранения товаров, доступных в магазине, и их соответствующих цен. Затем программа отображает ассортимент для пользователя.

Затем программа переходит в цикл. Пользователю предлагается ввести название товара, который он хочет купить. Если юзер вводит exit, алгоритм завершается и программа заканчивается.

При вводе названия товара, которого нет в ассортименте, мы оповещаем юзера, что товара нет в наличии, и продолжаем выполнение.

Если потенциальный клиент вводит название доступного товара, программа предлагает ввести количество продуктов, которые он хочет купить. Затем приложение рассчитывает стоимость заказа и добавляет цену.

В конце программа считает стоимость заказа и завершает работу. Приложение демонстрирует Continue для реализации упрощенного коммерческого проекта.

Return

Return применяется для завершения метода и вывода результата вычисления. Он также применяется в циклах для выхода и возврата значения.

Оператор return пишут для выхода из функции и возврата значения вызывающей стороне. Это удобно, когда нужно выполнить вычисления или итерации до совершения определенного условия и вернуть результат, основанный на нем.

Реализация return:

public class Main {
    public static void main(String[] args) {
        int[] arr = {17, 34, 45, 1, 8};
        int num = 45;
        int index = findIndex(arr, num);
        System.out.println("Найден " + num + " в наборе: " + index);
    }

    public static int findIndex(int[] arr, int num) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num) {
                return i; // Возврат результата вычислений и выход из цикла
            }
        }
        return -1; // возвращаем -1, если нет искомой цифры
    }
}

При итерации алгоритм остановится и немедленно вернет индекс, если найдет нужное число. После return не выполнится никакого дополнительного кода. 

Бесконечные циклы

Бесконечный цикл продолжает выполняться бесконечно, его условие выхода не принимает выражение False хотя бы в одном случае или условие выхода не определено. Алгоритм будет работать вечно или до прерывания внешним событием.

Вот пример:

while (true) {
  // любой код, за исключением break и return
}

Здесь результат значения условия всегда «Правда», поэтому цикл выполняется без остановки. Для прекращения цикла необходимо изменить условие на «Ложь».

Бесконечный цикл в языке Java в большинстве случаев — логическая ошибка со стороны разработчика. При неправильном подходе он может привести к тому, что программа перестает реагировать на запросы и завершится аварийно. 

Однако, иногда бесконечный цикл необходим. Например, в серверных процессах, операционных системах или приложениях реального времени. В этих случаях он обычно сочетается с оптимизацией. Это нужно для того, чтобы программа оставалась работоспособной и не потребляла много системных ресурсов.

Вложенные циклы

Они означают использование одного или нескольких циклов внутри другого. Обычно применяются для работы с двумерными массивами. 

Нарисуем узор в форме буквы X. Необходимо применять фрагмент с двумя циклами в Java для включения возможных комбинаций из тире и звездочек.

Реализуем:

public class Main {
    public static void main(String[] args) {
        int razmer = 7;

        for (int i = 0; i < razmer; i++) {
            for (int j = 0; j < razmer; j++) {
                if (i == j || i == razmer - j - 1) {
                    System.out.print("*");
                } else {
                    System.out.print("-");
                }
            }
            System.out.println();
        }
    }
}

Создаем квадратный узор с чередующимися рядами звезд и черточек, где звезды образуют форму «X» через середину квадрата. Размер квадрата установлен на 7 — это количество строк.

Результат:

*-----*
-*---*-
--*-*--
---*---
--*-*--
-*---*-
*-----*

Всегда будет выводится «X», вне зависимости от количества строк, благодаря проверке во вложенном цикле. Оператор if проверяет, находится ли текущая позиция цикла на главной диагонали (где i == j) или на противоположной диагонали (где i == razmer - j - 1). Когда одно из условий истинно, то в позиции печатается звезда. Если ложно — тире.

Итог

Мы рассказали какие есть циклы в Java. Используя их, разработчики могут упрощать свой код и создавать эффективные приложения.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
10 апреля 2023 г.
5643
17 минут чтения
Средний рейтинг статьи: 2.9
Пока нет комментариев