$ sudo teach IT
МОДУЛЬ 4 · УРОК 4

Break и continue — выход из цикла, пропуск итерации, метки для вложенных циклов, практика: поиск простых чисел

Break и continue — операторы, которые позволяют управлять потоком выполнения цикла. Break прерывает цикл, а continue пропускает текущую итерацию.

~25 минут Для новичков Java

Зачем нужны break и continue?

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

Представьте, что вы читаете книгу. Обычно вы читаете страница за страницей. Но:

  • break — вы бросаете книгу и закрываете её, потому что нашли нужную информацию. Читать дальше не нужно.
  • continue — вы пропускаете текущую страницу (например, она чистая или повторяется) и переходите к следующей.

Оператор break

break немедленно завершает цикл и программа продолжается с кода, следующего за циклом.

for (int i = 1; i <= 100; i++) {
    System.out.println(i);
    if (i == 5) {
        break;
    }
}
System.out.println("Цикл завершён после 5");

Вывод:

1
2
3
4
5
Цикл завершён после 5

Несмотря на то, что условие i <= 100, цикл прервался на i = 5, потому что break был выполнен.

Break в while

break работает с любым типом цикла — while, do-while, for:

int sum = 0;
int i = 1;

while (true) {
    sum += i;
    if (sum > 50) {
        System.out.println("Сумма превысила 50 при i = " + i);
        System.out.println("Сумма = " + sum);
        break;
    }
    i++;
}

System.out.println("Цикл завершён");

Вывод:

Сумма превысила 50 при i = 10
Сумма = 55
Цикл завершён

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

Практический пример: поиск элемента в массиве

int[] numbers = {12, 45, 7, 23, 56, 89, 34};
int target = 56;
int index = -1;

for (int i = 0; i < numbers.length; i++) {
    if (numbers[i] == target) {
        index = i;
        break;
    }
}

if (index != -1) {
    System.out.println("Элемент " + target + " найден по индексу " + index);
} else {
    System.out.println("Элемент не найден");
}

Вывод:

Элемент 56 найден по индексу 4

Без break цикл бы продолжился до конца массива, даже после нахождения элемента. Это лишняя работа.

Оператор continue

continue пропускает остаток текущей итерации и переходит к проверке условия (для while/do-while) или к инкременту и проверке условия (для for).

for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue;
    }
    System.out.println(i);
}

Вывод:

1
3
5
7
9

Выводятся только нечётные числа. Когда i чётное, continue пропускает System.out.println(i) и переходит к следующей итерации.

Continue vs без continue

Тот же результат можно получить без continue, используя if:

// С continue:
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue;
    }
    System.out.println(i);
}

// Без continue (тот же результат):
for (int i = 1; i <= 10; i++) {
    if (i % 2 != 0) {
        System.out.println(i);
    }
}

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

Практический пример: пропуск отрицательных чисел

int[] values = {5, -3, 8, -1, 12, -7, 3};
int sum = 0;

for (int i = 0; i < values.length; i++) {
    if (values[i] < 0) {
        continue;
    }
    sum += values[i];
}

System.out.println("Сумма положительных: " + sum);

Вывод:

Сумма положительных: 28

Когда элемент отрицательный, continue пропускает прибавление к сумме.

Continue в while и do-while

В циклах while и do-while continue переход к проверке условия. Будьте осторожны — если инкремент стоит после continue, он будет пропущен:

// ОПАСНО: инкремент после continue будет пропущен!
int i = 0;
while (i < 10) {
    if (i == 3) {
        continue;  // Вернётся к while, но i не увеличится → бесконечный цикл!
    }
    System.out.println(i);
    i++;
}

Этот код — бесконечный цикл! Когда i = 3, continue пропускает i++, и i навсегда остаётся равным 3.

Вот безопасный вариант:

int i = 0;
while (i < 10) {
    i++;
    if (i == 3) {
        continue;
    }
    System.out.println(i);
}

Вывод:

1
2
4
5
6
7
8
9
10

Совет: в for цикле инкремент выполняется ПОСЛЕ continue, поэтому бесконечный цикл с continue в for невозможен. В while будьте осторожны!

Метки для вложенных циклов

Когда циклы вложены друг в друга, break и continue работают только с внутренним циклом. Чтобы прервать внешний цикл, используются метки.

outer:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (i == 2 && j == 2) {
            break outer;
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}
System.out.println("Цикл завершён");

Вывод:

i=1, j=1
i=1, j=2
i=1, j=3
i=2, j=1
Цикл завершён

break outer прервал оба цикла — и внутренний, и внешний.

Continue с меткой

outer:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (j == 2) {
            continue outer;
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}
System.out.println("Цикл завершён");

Вывод:

i=1, j=1
i=2, j=1
i=3, j=1
Цикл завершён

continue outer пропускает остаток внешнего цикла для текущей итерации — то есть пропускает все j, кроме j=1, и переходит к следующему i.

Метки — это имена, которые ставятся перед циклом с двоеточием. outer: — имя метки (может быть любым). break outer — выход из цикла с этой меткой.

Практика: поиск простых чисел

Простое число — это число, которое делится только на 1 и на себя. Например, 2, 3, 5, 7, 11, 13. Найдём все простые числа от 2 до 30:

for (int num = 2; num <= 30; num++) {
    boolean isPrime = true;

    for (int div = 2; div * div <= num; div++) {
        if (num % div == 0) {
            isPrime = false;
            break;
        }
    }

    if (isPrime) {
        System.out.println(num + " — простое число");
    }
}

Вывод:

2 — простое число
3 — простое число
5 — простое число
7 — простое число
11 — простое число
13 — простое число
17 — простое число
19 — простое число
23 — простое число
29 — простое число

Обратите внимание на div * div <= num — нам не нужно проверять делители больше корня из числа. Если число не имеет делителей до корня — оно простое.

Практика: подсчёт вхождений символа

String text = "Программирование на Java — это интересно!";
char target = 'а';
int count = 0;

for (int i = 0; i < text.length(); i++) {
    if (text.charAt(i) == target) {
        count++;
    }
}

System.out.println("Символ '" + target + "' встречается " + count + " раз(а).");

Вывод:

Символ 'а' встречается 4 раз(а).

Практика: поиск第一个 делителя

int number = 36;
int firstDivisor = -1;

for (int i = 2; i <= number; i++) {
    if (number % i == 0) {
        firstDivisor = i;
        break;
    }
}

if (firstDivisor != -1) {
    System.out.println("Первый делитель " + number + " (больше 1): " + firstDivisor);
}

Вывод:

Первый делитель 36 (больше 1): 2

break останавливает поиск сразу после нахождения первого делителя.

Практика: ввод данных с валидацией

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String password = "java123";

        while (true) {
            System.out.println("Введите пароль:");
            String input = scanner.nextLine();

            if (input.equals(password)) {
                System.out.println("Добро пожаловать!");
                break;
            }

            System.out.println("Неверный пароль! Попробуйте снова.");
        }
    }
}

Этот код использует while (true) с break — бесконечный цикл, который прерывается только при правильном вводе.

Практика: пропуск дубликатов

int[] numbers = {1, 3, 5, 3, 7, 1, 9, 5, 3};
int count = 0;

for (int i = 0; i < numbers.length; i++) {
    boolean duplicate = false;

    for (int j = 0; j < i; j++) {
        if (numbers[i] == numbers[j]) {
            duplicate = true;
            break;
        }
    }

    if (!duplicate) {
        count++;
    }
}

System.out.println("Количество уникальных элементов: " + count);

Вывод:

Количество уникальных элементов: 5

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

Аналогия: break — как стоп-кнопка в лифте: нажали — лифт остановился на текущем этаже. continue — как кнопка «пропустить» в презентации: пропускаете текущий слайд и переходите к следующему.

Сравнение break и continue

Характеристика break continue
Действие Полностью прерывает цикл Пропускает текущую итерацию
Код после break Не выполняется Пропускается
Цикл продолжается? Нет Да (следующая итерация)
Использование Нашли искомое → выходим Неподходящий элемент → пропускаем

Практика: поиск всех простых делителей

Найдём все простые делители числа 60:

int number = 60;
System.out.println("Простые делители числа " + number + ":");

for (int i = 2; i <= number; i++) {
    if (number % i != 0) {
        continue;
    }

    boolean isPrime = true;
    for (int j = 2; j * j <= i; j++) {
        if (i % j == 0) {
            isPrime = false;
            break;
        }
    }

    if (isPrime) {
        System.out.print(i + " ");
    }
}
System.out.println();

Вывод:

Простые делители числа 60:
2 3 5

Здесь используются оба оператора: continue для пропуска чисел, которые не являются делителями, и break для раннего выхода из проверки на простоту.

Практика: бинарный поиск (упрощённый)

Бинарный поиск — эффективный алгоритм поиска в отсортированном массиве. Мы проверяем середину и сужаем диапазон поиска:

int[] sorted = {2, 5, 8, 12, 16, 23, 38, 45, 67, 91};
int target = 23;
int left = 0;
int right = sorted.length - 1;
int foundIndex = -1;

while (left <= right) {
    int mid = (left + right) / 2;

    if (sorted[mid] == target) {
        foundIndex = mid;
        break;
    } else if (sorted[mid] < target) {
        left = mid + 1;
    } else {
        right = mid - 1;
    }
}

if (foundIndex != -1) {
    System.out.println("Элемент " + target + " найден по индексу " + foundIndex);
} else {
    System.out.println("Элемент не найден");
}

Вывод:

Элемент 23 найден по индексу 5

break используется для немедленного выхода после нахождения элемента.

Практика: проверка пароля с ограничением попыток

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String correctPassword = "java123";
        int maxAttempts = 3;

        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            System.out.println("Попытка " + attempt + "/" + maxAttempts + ":");
            System.out.println("Введите пароль:");
            String input = scanner.nextLine();

            if (input.equals(correctPassword)) {
                System.out.println("Добро пожаловать!");
                break;
            }

            System.out.println("Неверный пароль!");
        }
    }
}

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

Практика: пропуск строк при обработке

String[] lines = {"Hello", "", "World", "", "Java", "Programming", ""};

for (int i = 0; i < lines.length; i++) {
    if (lines[i].isEmpty()) {
        continue;
    }
    System.out.println("Строка " + (i + 1) + ": " + lines[i]);
}

Вывод:

Строка 1: Hello
Строка 3: World
Строка 5: Java
Строка 6: Programming

continue пропускает пустые строки.

Практика: поиск с возвратом индекса

int[] data = {45, 12, 67, 23, 89, 34, 11, 56};
int target = 89;
int resultIndex = -1;

for (int i = 0; i < data.length; i++) {
    if (data[i] == target) {
        resultIndex = i;
        break;
    }
}

System.out.println("Результат: индекс " + resultIndex);

Вывод:

Результат: индекс 4

Практика: фильтрация данных

int[] temperatures = {23, -5, 18, 32, -12, 27, 8, -3, 15};

System.out.println("Температуры выше нуля:");
for (int temp : temperatures) {
    if (temp <= 0) {
        continue;
    }
    System.out.println(temp + "°C");
}

System.out.println("\nТемпературы ниже -10:");
for (int temp : temperatures) {
    if (temp >= -10) {
        continue;
    }
    System.out.println(temp + "°C");
}

Вывод:

Температуры выше нуля:
23°C
18°C
32°C
27°C
8°C
15°C

Температуры ниже -10:
-12°C

Практика: цикл с несколькими условиями выхода

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random random = new Random();
        int attempts = 0;
        int maxAttempts = 10;

        while (true) {
            attempts++;
            int roll = random.nextInt(6) + 1;

            System.out.println("Попытка " + attempts + ": выпало " + roll);

            if (roll == 6) {
                System.out.println("Ура! Выпало 6!");
                break;
            }

            if (attempts >= maxAttempts) {
                System.out.println("Попытки исчерпаны!");
                break;
            }
        }
    }
}

Здесь два условия для break: выигрыш или исчерпание попыток.

Практика: поиск первого и последнего вхождения

int[] data = {5, 3, 7, 3, 9, 3, 2};
int target = 3;
int firstIndex = -1;
int lastIndex = -1;

for (int i = 0; i < data.length; i++) {
    if (data[i] == target) {
        if (firstIndex == -1) {
            firstIndex = i;
        }
        lastIndex = i;
    }
}

System.out.println("Первое вхождение: индекс " + firstIndex);
System.out.println("Последнее вхождение: индекс " + lastIndex);

Вывод:

Первое вхождение: индекс 1
Последнее вхождение: индекс 5

Практика: пропуск чётных индексов

int[] values = {10, 20, 30, 40, 50, 60, 70, 80};

System.out.println("Элементы на нечётных позициях:");
for (int i = 0; i < values.length; i++) {
    if (i % 2 == 0) {
        continue;
    }
    System.out.println("Индекс " + i + ": " + values[i]);
}

Вывод:

Индекс 1: 20
Индекс 3: 40
Индекс 5: 60
Индекс 7: 80

Золотое правило: используйте break когда нашли то, что искали. Используйте continue когда нужно пропустить неподходящий элемент и перейти к следующему.

Итоги урока

  • break — немедленно завершает цикл
  • continue — пропускает остаток текущей итерации
  • Оба работают с while, do-while, for
  • Для вложенных циклов используются метки: break outer, continue outer
  • continue в while может привести к бесконечному циклу, если инкремент после него
  • В for инкремент выполняется после continue, поэтому бесконечный цикл невозможен
  • break полезен для раннего выхода при нахождении элемента
  • continue полезен для пропуска неподходящих элементов

Следующий урок

В следующем уроке мы изучим вложенные циклы — циклы внутри циклов. Узнаем, как создавать таблицы, матрицы и сложные паттерны.

Урок 5: Вложенные циклы →

Тест по break и continue

1 вопрос

Поиск простых чисел

Premium

Сумма чётных чисел

Premium