Кажуть, що найкращий програміст – ледачий програміст. Замість того, щоб здійснювати однотипні дії кілька разів, він придумає алгоритм, який зробить цю роботу за нього. А ще він зробить його добре, щоб не потрібно було переробляти.
Приблизно так, щоб багато разів не писати один і той самий код, придумали цикли. Уявімо, що нам потрібно вивести в консоль числа від 0 до 99. Код без циклу:
System.out.println(0);
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
// Тощо
Цей код займе 100 рядків! Дуже багато. А ось який вигляд це матиме з циклом:
for(int i = 0; i < 100; i++) {
System.out.println(i);
}
Всього 3 рядки!
Що таке цикли for?
Цикл for – це керівна конструкція програмного коду, яка порушує лінійність виконання алгоритму і дає змогу виконати зазначений код безліч разів. Наприклад, необхідно прийняти 30 крапель ліків. Алгоритм буде приблизно такий:- Приготувати склянку.
- Відкрити кришку.
- Отримати 1 краплю.
- Отримати 2 краплю. …
- Отримати 30 краплю.
- Закрити ліки.
- Прийняти отриману порцію.
- Приготувати склянку.
- Відкрити кришку крапель.
- Отримати 30 крапель.
- Закрити ліки.
- Прийняти отриману порцію.
Принцип роботи циклу for
For-цикл використовується таким чином:
for(<початкова точка>; <умова завершення>; <оператори лічильника>) {
// Тіло циклу
}
Приклад перебору цифр від 0 до 5 і виведення кожної в консоль:
for(int i = 0; i < 5; i++) {
System.out.println(i);
}
Виведення:
0
1
2
3
4
Якщо перекласти цей запис людською мовою, вийде таке:
"Створи змінну i з початковим значенням 0, поки вона не досягне 5, додавай до неї по 1 і на кожному кроці записуй значення i в консоль."
В основі роботи циклу for в Java лежать три стадії, їх можна проілюструвати такою схемою:
Умова завершення циклу – це булевий вираз. Якщо він хибний, цикл буде завершено. У прикладі вище змінна i збільшується на 1. Якщо її значення менше за 5, цикл триває. Але щойно i стане більшим або дорівнюватиме 5, цикл припиниться.
Оператор лічильника – вираз, який виконує перетворення змінної лічильника. У прикладі вище змінна i збільшувалася на 1. Тобто цикл буде виконано рівно 5 разів. Якщо оператор лічильника додаватиме по 2 до змінної i, результат буде іншим:
for(int i = 0; i < 5; i = i + 2) {
System.out.println(i);
}
Виведення:
0
2
4
Також можна множити змінну, ділити, зводити в ступінь, загалом, робити все, що завгодно. Головне, щоб внаслідок перетворення вийшло число.
Тіло циклу – будь-який код, який може бути виконаний. У прикладі вище в тілі циклу було виведення значення змінної i в консоль, проте вміст цього тіла обмежений завданням і фантазією.
Узагальнюючи всю схему, принцип цього циклу – for – наступний: код, що знаходиться в тілі циклу, буде виконано стільки разів, скільки перетворень виконає оператор лічильника до того, як буде досягнуто умови завершення циклу.
Якщо задати умову завершення циклу як true:
for(int i = 0; true; i++) {
if(i % 1000000 == 0) System.out.println(i);
}
System.out.println("Loop ended");
То код після циклу буде позначений помилкою unreachable statement, оскільки ніколи не буде виконаний.
Задача на кмітливість: чи буде унаслідок запуску коду нижче виведено в консоль "Loop ended" або цикл виконуватиметься нескінченно?
for(int i = 0; i > -1; i++) {
if(i % 1000000 == 0) System.out.println(i);
}
System.out.println("Loop ended");
Відповідь: буде. Змінна i рано чи пізно досягне максимального значення, а подальше збільшення перетворить її на максимальне від'ємне, внаслідок чого умову завершення буде виконано (i < = -1).
Цикл forEach
Під час роботи з циклами іноді доводиться перебирати масиви або колекції. Зазвичай масив можна перебрати за допомогою циклу for:
public void printAllElements(String[] stringArray) {
for(int i = 0; i < stringArray.length; i++) {
System.out.println(stringArray[i]);
}
}
І це правильно. Однак, для перебору всіх елементів масиву почергово придумали конструкцію forEach. Її сигнатура така:
for(<Тип елемента> <Ім'я змінної, куди буде записаний черговий елемент> : <Назва масиву>) {
// Тіло циклу
}
Перебрати масив рядків і вивести кожен у консоль можна в такий спосіб:
public void printAllElements(String[] stringArray) {
for(String s : stringArray) {
System.out.println(s);
}
}
Теж коротко і лаконічно. Найголовніше, немає потреби думати про лічильник і про умови завершення, все вже зроблено за нас.
Як використовують цикли for
А тепер розглянемо кілька прикладів використання циклу for в Java для розв'язання різноманітних завдань.Зворотний цикл (від більшого до меншого)
for(int i = 5; i > 0; i--) {
System.out.println(i);
}
Виведення:
5
4
3
2
1
Кілька змінних і збільшення лічильника в тілі циклу
У циклі for можна використовувати кілька змінних, наприклад їх можна перетворювати в операторі лічильника:
int a = 0;
for(int i = 5; i > 0; i--, a++) {
System.out.print("Крок: " + a + "Значення: ");
System.out.println(i);
}
Виведення:
Крок: 0 Значення: 5
Крок: 1 Значення: 4
Крок: 2 Значення: 3
Крок: 3 Значення: 2
Крок: 4 Значення: 1
Або оголосити дві змінні і йти циклом, доки вони не дорівнюватимуть одна одній:
for(int i = 5, j = 11; i != j; i++, j--) {
System.out.println("i: " + i + " j: " + j);
}
Виведення:
i: 5 j: 11
i: 6 j: 10
i: 7 j: 9
Навряд чи ця дія має якусь цінність, але знати про таку можливість корисно.
У циклі for також можна створювати внутрішні цикли. У цьому разі кількість кроків циклу буде множитися:
for(int i = 0; i < 5; i++) {
System.out.print(i + " | ");
for(int j = 0; j < 5; j++) {
System.out.print(j + " ");
}
System.out.print('\n');
}
Виведення:
0 | 0 1 2 3 4
1 | 0 1 2 3 4
2 | 0 1 2 3 4
3 | 0 1 2 3 4
4 | 0 1 2 3 4
У циклі з лічильником j є можливість звертатися до лічильника зовнішнього циклу. Завдяки цьому вкладені цикли – ідеальний спосіб обходу двовимірного, тривимірного та інших масивів:
int[][] array = { {0, 1, 2, 3, 4 },
{1, 2, 3, 4, 5},
{2, 3, 4, 5, 6},
{3, 4, 5, 6, 7}};
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
System.out.print('\n');
}
Виведення:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
Дострокове завершення циклу
Якщо під час обробки циклу потрібно його перервати, використовуйте оператор break, який зупиняє роботу поточного тіла циклу. Усі наступні ітерації також пропускаються:
public void getFirstPosition(String[] stringArray, String element) {
for (int i = 0; i < stringArray.length; i++) {
if(stringArray[i].equals(element)) {
System.out.println(i);
break;
}
}
}
Метод виведе позицію першого шуканого елемента в масиві:
String[] array = {"one", "two", "three", "Jeronimo"};
getFirstPosition(array, "two");
Виведення:
1
Нескінченний цикл
Ще один спосіб створити нескінченний цикл for – залишити порожньою область оголошення лічильника, умову завершення та оператор лічильника:
for (;;;) {
}
Але зваж, що здебільшого нескінченний цикл – свідчення логічної помилки. У такого циклу обов'язково має бути умова завершення.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ