Java: Цикл For

С помощью цикла while решают любую задачу перебора, но его отличает многословность. Для while приходится отдельно заводить счетчик, отдельно задавать условие остановки и отдельно менять счетчик в теле цикла. Когда циклов немного, это терпимо. В реальном коде циклы встречаются на каждом шагу, и управлять тремя частями вручную утомительно, особенно когда количество повторов известно заранее.

Для таких случаев в Java есть цикл for. Он собирает все три части в одну строку. Посмотрим реализацию переворота строки через for:

public static String reverseString(String str) {
    var result = "";
    for (var i = 0; i < str.length(); i++) {
        result = str.charAt(i) + result;
    }

    return result;
}

App.reverseString("code"); // "edoc"

Запись i++ увеличивает счетчик на единицу. Это короткая форма для i = i + 1, и в заголовке цикла она встречается чаще всего. Сам код можно описать словами так:

Цикл с индексом i начинается со значения 0, повторяется, пока i < str.length(), и после каждого шага увеличивает i на единицу

В заголовке цикла for ровно три части, разделенные точками с запятой:

  1. Начальное значение счетчика. Этот код выполняется один раз перед первой итерацией
  2. Предикат — условие повторения. Проверяется перед каждой итерацией, точно так же как в while
  3. Изменение счетчика. Этот код выполняется в конце каждой итерации

В остальном принцип работы такой же, как у while.

Разбор по шагам

Разберем, как отрабатывает цикл при вызове reverseString("go!"). До цикла result равен пустой строке:

reverseString("go!")

до цикла: result = ""

i=0: charAt(0) = 'g'
result = 'g' + ""   = "g"

i=1: charAt(1) = 'o'
result = 'o' + "g"  = "og"

i=2: charAt(2) = '!'
result = '!' + "og" = "!og"

Каждый символ берется по индексу слева направо и приклеивается к началу результата. Поэтому строка собирается в обратном порядке.

Сравнение с while

Один и тот же перебор строки на двух циклах выглядит так:

for (var i = 0; i < str.length(); i++) {     var i = 0;
    System.out.println(str.charAt(i));       while (i < str.length()) {
}                                                System.out.println(str.charAt(i));
                                                 i = i + 1;
│                                            │   }
└── счетчик задан в одной строке             └── счетчик размазан по телу

Цикл for держит все управление счетчиком в заголовке, поэтому тело остается чистым. Когда количество повторов понятно заранее, for читается лучше. Когда заранее неясно, сколько будет итераций, например при поиске простого числа, удобнее while.

Покажем еще пример с числовым счетчиком. Сложим числа от 0 до 9:

var sum = 0;
for (var i = 0; i < 10; i++) {
    sum = sum + i;
}

System.out.println(sum); // => 45

Счетчик начинается с нуля, цикл идет, пока i < 10, и на каждом шаге i растет на единицу. Внутри тела остается только накопление суммы.

Задание

Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа.

App.encrypt("move"); // "omev"
App.encrypt("attack"); // "taatkc"
// Если число символов нечётное
// то последний символ остается на своем месте
App.encrypt("go!"); // "og!"

Реализуйте статический метод App.encrypt(), который принимает на вход исходное сообщение и возвращает зашифрованное.

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются