Урок 15. Циклы и методы в Java (часть 1)

Циклы в Java

В этом уроке мы узнаем, как повторно выполнять части нашего кода контролируемым образом, глядя на различные типы циклов в Java. Подробнее познакомимся с циклами: while, do-while, for. Постараемся определить в каких случаях, какой из циклов наиболее пригоден для использования.

Затем мы кратко рассмотрим тему случайных чисел (random numbers). Посмотрим на Java-класс Random и как он нам может помочь в нашей игре.

Цикл как следует из названия – это способ выполнения одной и той же части кода необходимое количество раз (при этом результат выполнения кода в цикле необязательно будет повторяться). Количество повторений выполнения цикла может быть, как определенно заранее, так и быть неизвестным самому программисту. Мы рассмотрим основные типы циклов, которыми нам предлагает воспользоваться язык Java. А после внедрим некоторые из них в нашу игру тем самым усовершенствовав её.

 

Цикл While

Цикл while имеет самый простой синтаксис. Вспомните if-инструкцию, которую мы изучали чуть ранее. В условное выражение оператора if (то, что заключено в скобочки после слова if) можно поместить практически любую комбинацию операторов и переменных. Если выражение будет истинным (true), то код, заключенный в тело блока if будет выполнен. Аналогичным образом в цикле while мы помещаем выражение, которое может вычисляться в true или false, как показано в этом коде:

int x = 10;

while(x > 0){
     x--;
     //x уменьшается на один каждый проход цикла
}

Что здесь происходит? Первым делом за пределами цикла while мы объявили переменную x типа int и присвоили этой переменной значение “10”. Далее начинается цикл while, в условии которого написано x > 0” – это означает, что код, написанный в теле цикла while будет выполняться до тех пор, пока переменная x больше 0 и условие не достигнет значения false. Следовательно, код выполнится 10 раз(x=10,x>0 ; x=9,x>0 ; x=8,x>0 ; x=7,x>0 ; x=6,x>0 ; x=5,x>0 ; x=4,x>0 ; x=3,x>0 ; x=2,x>0 ; x=1,x>0). В первый проход цикла x = 10, во второй уже 9, в третий 8 и т.д. И когда x будет равен 0, то условие захода в цикл не выполнится, и программа продолжится со следующей строки после окончания цикла.

Также, как и в операторе if, возможна такая ситуация, при которой цикл не будет выполнен ни разу. Взгляните на следующий пример:

int x = 10;

while(x > 10){
     //какой-нибудь код
     //но он никогда не выполнится, пока x больше 10
}

Кроме того, нет ограничений на сложность выражения условия или объем кода, который может быть записан в теле цикла:

int playerLives = 3;
int alienShips = 10;

while(playerLives >0 && alienShips >0){
     //Весь игровой код здесь
     //...
     //...
     // и т.д.
}
//программа продолжится здесь, когда или playerLives или alienShips = 0

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

Стоит отметить, что как только программа входит в тело цикла, он будет выполнен, даже если условие цикла станет false, где-нибудь в теле цикла, т.к. условие проверяется только при входе:

int x = 1;

while(x > 0){
     x--;
     //x теперь равен 0 и условие в следующий раз примет значение false
     //Но эта строка выполнится
     //И эта
     //И даже эта
}

В примере выше тело цикла выполнится один раз. Помимо этого, можно установить такое условие, что цикл будет выполняться вечно – это называется бесконечный цикл. Вот пример:

int x = 0;

while(true){
     x++; //Я буду становиться очень большим!
}

Выход их цикла. Ключевое слово break

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

int x = 0;

while(true){
     x++; //Я буду становиться очень большим!
     break; //Нет, не будешь!
     //код здесь не будет достигнут
}

Наверняка вы уже догадались о том, что возможно сочетать различные инструменты принятия решений, такие как if, else, switch внутри нашего цикла while и других циклах, которые рассмотрим чуть ниже. К примеру:

int x = 0;
int tooBig = 10;

while(true){
     x++; //Я буду становиться очень большим!
     if(x == tooBig){
     break; //Нет, не будешь.
} 
//код здесь будет доступен до тех пор пока x не станет равен 10
}

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

 

Ключевое слово continue

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

int x = 0;
int tooBig = 10;
int tooBigToPrint = 5;

while(true){
     x++; //Я буду становиться очень большим!
     if(x == tooBig){
     break;
     } //Нет, не будешь.
//код здесь будет доступен только пока x не станет равен 10
     if(x >= tooBigToPrint){
     //больше не будет выводиться на экран, но цикл будет продолжаться
     continue;
     }
//код здесь будет доступен пока x не станет равен 5
//код для вывода x на экран
}

Пояснение: объявляем и инициализируем переменные. Заходим в цикл — прибавляем к значению переменной единицу (теперь x = 1). Проверка «1 равно 10?» — false — первый оператор if не выполняется. Следующая проверка «1 больше или равен 5?» — false — второй оператор if не выполняется. Выводим x на экран.

Рассмотрим вариант, когда x будет принимать значение  5 при входе в цикл. Заходим в цикл — прибавляем к значению переменной x единицу (теперь x = 6). Проверка «6 равно 10?» — false — первый оператор if не выполняется. Следующая проверка «6 больше или равен 5?» — true — заходим в тело if — continue, выходим из цикла и проверяем условие входа в цикл.

Теперь вариант, когда x будет принимать значение 9 при входе в цикл. Заходим в цикл — прибавляем к значению переменной единицу (теперь x  = 10). Проверка «10 равно 10?» — true — заходим в тело ifbreak, выходим из цикла и код продолжится за закрывающейся фигурной скобкой цикла while.

Цикл do-while

Почти тоже самое, что и предыдущий цикл за исключением одной особенности – проверка выполнения условного выражения будет происходить после тела цикла. Это означает, что цикл do-while всегда будет выполняться хотя бы один раз. Взгляните на пример:

int x = 0;
do {
     x++;
} while(x < 10);
//x теперь = 10

Ключевые слова break, continue также можно использовать в данном цикле.

Цикл for

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

for(int i = 0; i < 10; i++){
     //Что-то, что должно произойти 10 раз будет записано здесь
}

Как это видит компилятор? Вот так:

for(объявление и инициализация; условие; изменить после каждого прохождения цикла){
     // тело цикла
}

Уточним:

  • Объявление и инициализация – мы создали новую переменную типа int с именем i и присвоили ей значение 0;
  • Условие – подобно другим рассмотренным ранее циклам, тут мы проверяем условие вхождения в цикл. Если значение вычисляется как true, то входим в тело цикла;
  • Изменить после каждого прохождения цикла – в примере выше i++ означает то, что после очередного прохода цикла мы к значению переменной i добавляем единицу (1). Более того, мы можем в изменении переменной написать и i, чтобы отнимать единицу, например:
for(int i = 10; i > 0; i--){
     //обратный отсчет
}
//ключ на старт, i = 0

Ключевые слова break, continue также можно использовать в данном цикле.

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