Основы синтаксиса Java

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

Структура программы Java, метод main и вывод данных в консоль

Структура программы Java, метод main и вывод данных в консоль

Добро пожаловать на курс «Основы синтаксиса Java». Это наша первая лекция, и сегодня мы заложим фундамент, на котором будет строиться всё ваше дальнейшее обучение. Мы разберем анатомию Java-приложения, узнаем, с чего начинается выполнение любой программы, и научим компьютер «разговаривать» с нами через консоль.

Философия Java: Пиши один раз, запускай везде

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

  1. Исходный код (.java): Это то, что пишет программист. Текст, понятный человеку.
  2. Компиляция: Специальная программа (компилятор javac) проверяет ваш код на ошибки и переводит его в байт-код.
  3. Байт-код (.class): Это набор инструкций, который не зависит от операционной системы.
  4. JVM (Java Virtual Machine): Виртуальная машина Java, установленная на компьютере, читает байт-код и переводит его в команды, понятные конкретному устройству.

Именно благодаря JVM работает принцип: Write Once, Run Anywhere (Написал один раз — запускай везде).

Анатомия Java-программы

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

Минимальная структура программы выглядит так:

public class FirstProgram {
    // Здесь будет код
}

Правило именования файла

Это критически важное правило, которое новички часто нарушают: имя файла должно в точности совпадать с именем публичного класса.

  • Если класс называется FirstProgram, то файл обязательно должен называться FirstProgram.java.
  • Java чувствительна к регистру (case-sensitive). FirstProgram и firstprogram — это два разных имени.

Метод main: Точка входа

Представьте огромное здание с тысячей комнат. Чтобы попасть внутрь, вам нужна главная дверь. В Java такой дверью является метод main. Когда вы запускаете программу, JVM ищет именно этот метод, чтобы начать выполнение инструкций.

Полная сигнатура (объявление) метода выглядит пугающе для новичка, но мы разберем каждое слово:

public static void main(String[] args) {
    // Команды выполняются здесь
}

Давайте препарируем эту строку:

  1. public: Модификатор доступа. Он говорит о том, что этот метод «публичный», то есть доступен для вызова извне (в данном случае — виртуальной машиной Java).
  2. static: Означает «статический». Это позволяет JVM вызвать метод main без необходимости создавать объект (экземпляр) класса. Программа еще не начала работать, объектов еще нет, но метод уже нужно вызвать.
  3. void: Тип возвращаемого значения. В английском языке void означает «пустота». Это ключевое слово сообщает, что метод просто выполняет работу и не возвращает никакого результата (числа или строки) обратно.
  4. main: Имя метода. Это зарезервированное имя, которое ищет JVM.
  5. String[] args: Аргументы метода. Это массив строк, который позволяет передавать данные в программу при её запуске из командной строки. Даже если мы ничего не передаем, эта часть обязательна.

Тело программы и синтаксис

Код, который должен выполняться, пишется внутри фигурных скобок {}. В Java фигурные скобки обозначают начало и конец блока кода.

  • Скобки после class FirstProgram ограничивают весь класс.
  • Скобки после main(...) ограничивают метод main.

Точка с запятой

В русском языке мы ставим точку в конце предложения. В Java мы ставим точку с запятой ; в конце каждой команды (инструкции). Это сигнал компилятору: «Команда закончена, переходи к следующей».

Пропущенная точка с запятой — самая частая ошибка начинающего программиста, из-за которой код не компилируется.

Вывод данных в консоль

Чтобы программа могла «пообщаться» с нами, мы используем вывод текста на экран. Для этого в Java существует стандартная команда:

System.out.println("Привет, мир!");

Разберем, что здесь происходит:

  • System: Встроенный класс, предоставляющий доступ к системным ресурсам.
  • out: Объект внутри класса System, отвечающий за стандартный поток вывода (обычно это консоль).
  • println: Метод (команда), который печатает переданный текст и переводит курсор на новую строку.

print vs println

Существует два похожих метода:

  1. System.out.println() — печатает текст и в конце добавляет невидимый символ переноса строки. Следующий текст появится ниже.
  2. System.out.print() — печатает текст и оставляет курсор на той же строке. Следующий текст «приклеится» к этому.

Пример:

public class OutputExample {
    public static void main(String[] args) {
        System.out.print("Java ");
        System.out.print("это ");
        System.out.println("круто!");
        System.out.println("Новая строка.");
    }
}

Результат в консоли:

Java это круто!
Новая строка.

Обратите внимание: первые три команды собрали текст в одну строку, потому что println был использован только в третьей команде.

Комментарии в коде

Хороший код должен быть понятен не только машине, но и человеку. Для заметок программисты используют комментарии. Компилятор полностью игнорирует их.

  • Однострочный комментарий: Начинается с //. Всё, что написано после этих символов до конца строки, не выполняется.
  • Многострочный комментарий: Заключается между /* и */. Позволяет писать длинные пояснения на несколько строк.
/*
  Это наша первая программа.
  Она выводит приветствие.
*/
public class Hello {
    public static void main(String[] args) {
        // Эта команда выводит текст
        System.out.println("Hello, Java!");
    }
}

Итоговый чек-лист синтаксиса

Чтобы ваша первая программа заработала, проверьте себя по этому списку:

  1. Весь код находится внутри class.
  2. Имя файла совпадает с именем класса (включая регистр букв).
  3. Есть метод public static void main(String[] args).
  4. Текстовые строки заключены в двойные кавычки "текст".
  5. В конце каждой команды стоит точка с запятой ;.
  6. Все открытые фигурные скобки { имеют закрывающую пару }.

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

Переменные, примитивные типы данных и основы работы со строками

Переменные, примитивные типы данных и основы работы со строками

В предыдущей лекции мы научились создавать каркас Java-приложения и выводить текст в консоль. Но программы, которые просто печатают «Привет, мир!», не очень полезны. Настоящая сила программирования заключается в обработке данных. Чтобы работать с данными — числами, текстом, логическими значениями — нам нужно научиться их хранить и изменять.

Сегодня мы разберем понятие переменной, изучим «строительные блоки» языка Java — примитивные типы данных, и научимся работать с текстом с помощью строк.

Что такое переменная?

Представьте, что оперативная память вашего компьютера — это огромный склад с пустыми ячейками. Чтобы программа могла запомнить какое-то значение (например, возраст пользователя или цену товара), ей нужно «арендовать» ячейку на этом складе, дать ей имя и положить туда данные.

Переменная — это именованная область памяти, предназначенная для хранения данных определенного типа.

Создание переменной

В Java создание переменной происходит в два этапа (часто объединяемых в один):

  1. Объявление (Declaration): Мы сообщаем компьютеру: «Выдели место под переменную такого-то типа и назови её так-то».
  2. Инициализация (Initialization): Мы кладем в эту переменную первое значение.

Синтаксис выглядит так:

// ТипДанных имяПеременной = Значение;
int age = 25;

Разберем эту строку:

  • int — тип данных (целое число).
  • age — имя переменной.
  • = — оператор присваивания (положить значение справа в переменную слева).
  • 25 — само значение (литерал).
  • ; — конец команды.

Java — язык со строгой статической типизацией. Это значит, что если вы создали переменную для хранения целых чисел (int), вы не можете положить туда текст или дробное число. Коробка для обуви не подходит для хранения воды.

Правила именования (Naming Conventions)

Чтобы ваш код был профессиональным, следуйте правилам:

  • camelCase: Если имя состоит из нескольких слов, первое пишется с маленькой буквы, а каждое следующее — с большой. Пример: myAge, bankAccountBalance, numberOfStudents.
  • Смысл: Имя должно отвечать на вопрос «что внутри?». Избегайте имен вроде a, x, data. Используйте width, userName, totalCount.
  • Ограничения: Имя может содержать буквы, цифры, _ и $, но не может начинаться с цифры.

Примитивные типы данных

В Java существует всего 8 примитивных типов данных. Они называются «примитивными», потому что хранят простые значения и встроены в само ядро языка. Они не являются объектами (в отличие от всего остального в Java).

Мы разделим их на 4 группы.

1. Целые числа (Integers)

Используются для счета предметов, индексов, идентификаторов. Дробной части у них нет.

Тип Размер (бит) Диапазон значений Когда использовать
byte 8 от -128 до 127 Очень редко, для экономии памяти в массивах
short 16 от -32 768 до 32 767 Редко, для совместимости со старыми библиотеками
int 32 от -2 млрд до 2 млрд Стандартный выбор для любых целых чисел
long 64 Огромные числа Когда не хватает int (население Земли, ID в БД)

Пример использования:

byte smallNumber = 100;
int salary = 50000;
long population = 8000000000L; // Обратите внимание на 'L' в конце

Важно: Если вы пишете очень большое число для типа long, в конце нужно добавить букву L (или l), иначе компилятор подумает, что это int, и выдаст ошибку, если число не влезает в диапазон int.

Чтобы понять, сколько значений может хранить тип данных, используется формула:

N=2bN = 2^b

где NN — общее количество уникальных значений, которые можно записать, а bb — количество бит, выделенных под этот тип данных. Например, для типа byte (88 бит) это 256256 значений.

2. Числа с плавающей точкой (Floating-Point)

Используются для дробных чисел (цены, вес, научные вычисления).

Тип Размер (бит) Точность Когда использовать
float 32 6-7 знаков после запятой Редко, для графики или экономии памяти
double 64 15-16 знаков после запятой Стандартный выбор для дробных чисел

Пример:

double pi = 3.14159;
float temperature = 36.6f; // Обратите внимание на 'f' в конце

Важно: Любое дробное число в коде (например, 3.14) Java по умолчанию считает типом double. Чтобы присвоить его переменной типа float, нужно обязательно добавить суффикс f или F.

3. Символьный тип (Character)

Тип char используется для хранения одного символа. Это может быть буква, цифра или специальный знак.

  • Занимает 16 бит.
  • Использует кодировку Unicode (позволяет хранить символы любых языков, включая эмодзи).
  • Значение обязательно заключается в одинарные кавычки.
char letter = 'A';
char digit = '7';
char symbol = '$';

4. Логический тип (Boolean)

Тип boolean самый простой, но самый важный для логики программы. Он может принимать только два значения:

  • true (истина)
  • false (ложь)
boolean isJavaFun = true;
boolean isWinter = false;

Этот тип данных будет основным инструментом, когда мы начнем изучать условные операторы (если... то...).

Основы работы со строками (String)

Вы наверняка заметили, что мы не упомянули текст. Дело в том, что строка в Java не является примитивным типом. Строка — это объект.

Тип данных называется String (с большой буквы, так как это имя класса).

String greeting = "Привет, Java!";
String empty = ""; // Пустая строка

Особенности строк:

  1. Значение заключается в двойные кавычки.
  2. Строки неизменяемы (Immutable). Когда вы «изменяете» строку, на самом деле в памяти создается новая, а старая выбрасывается.

Конкатенация (Склеивание)

Самая частая операция со строками — это их объединение. Для этого используется знак +.

String firstName = "Иван";
String lastName = "Иванов";
String fullName = firstName + " " + lastName;

System.out.println(fullName); // Выведет: Иван Иванов

Магия плюса

Если вы попробуете сложить строку и число, Java автоматически превратит число в строку и «приклеит» его.

int age = 20;
String message = "Мне " + age + " лет";
System.out.println(message); // Выведет: Мне 20 лет

Но будьте осторожны с порядком действий!

System.out.println("Сумма: " + 2 + 2); // Выведет: Сумма: 22
System.out.println(2 + 2 + " - сумма"); // Выведет: 4 - сумма

В первом случае Java видит строку, затем +, и превращает двойку в строку. Во втором случае сначала идет математическое сложение чисел, а потом результат склеивается с текстом.

Арифметика и нюансы деления

С числовыми переменными можно производить стандартные математические операции: +, -, * (умножение), / (деление), % (остаток от деления).

Однако есть важный нюанс при делении целых чисел.

int a = 5;
int b = 2;
System.out.println(a / b);

Что выведет этот код? Вы можете ожидать 2.5, но правильный ответ: 2.

Почему? Потому что мы делим целое число на целое число. Результат тоже обязан быть целым. Дробная часть просто отбрасывается (не округляется, а отрезается).

Если вы хотите получить дробный результат, хотя бы одно из чисел должно быть дробным (double или float).

double x = 5.0;
int y = 2;
System.out.println(x / y); // Выведет: 2.5

Итог

Сегодня мы заполнили наш склад инструментами. Теперь вы знаете:

  1. Как создавать переменные (тип имя = значение;).
  2. Какие бывают примитивы (чаще всего вы будете использовать int, double и boolean).
  3. Что String — это не примитив, но с ним легко работать через +.
  4. Как Java обращается с типами при математических операциях.

В следующей статье мы научимся управлять потоком выполнения программы, используя условные операторы. Мы заставим программу принимать решения.

Арифметические операции, логические операторы и операции сравнения

Арифметические операции, логические операторы и операции сравнения

Добро пожаловать на третью лекцию курса «Основы синтаксиса Java». В прошлый раз мы создали наши первые переменные — «коробки» для хранения данных. Но просто хранить данные скучно. Компьютеры были созданы для того, чтобы вычислять (от англ. compute — вычислять).

Сегодня мы превратим вашу Java-программу в мощный калькулятор и научим её принимать решения. Мы разберем, как складывать и умножать, как сравнивать величины и как строить сложную логику, подобную человеческому мышлению.

Арифметические операции

В основе любого процессора лежит Арифметико-логическое устройство (ALU). Java предоставляет нам прямой доступ к этим возможностям через операторы. Большинство из них вам знакомы со школьных уроков математики.

Базовые операторы

Рассмотрим основные действия над числами (типы int, double, long и т.д.):

  • + (Сложение): Суммирует два числа.
  • - (Вычитание): Вычитает второе число из первого.
  • * (Умножение): Перемножает числа.
  • / (Деление): Делит первое число на второе.
int a = 10;
int b = 5;

System.out.println(a + b); // 15
System.out.println(a - b); // 5
System.out.println(a * b); // 50
System.out.println(a / b); // 2

Оператор остатка от деления (%)

В программировании есть оператор, который используется гораздо чаще, чем в обычной жизни. Это остаток от деления, обозначаемый символом % (процент).

Математически это можно записать так:

r=a(modn)r = a \pmod n

Где rr — это остаток, aa — делимое, а nn — делитель. Результат операции — это то, что осталось и не поделилось нацело.

Примеры:

  • 10 % 3 равно 1 (так как 10 = 3 * 3 + 1)
  • 4 % 2 равно 0 (делится без остатка)
  • 5 % 2 равно 1

Зачем это нужно? Оператор % незаменим для определения четности числа (если x % 2 == 0, то число четное) или для зацикливания процессов (например, чтобы цвет менялся каждые 3 секунды).

Инкремент и декремент

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

  • ++ (Инкремент): Увеличивает переменную на 1.
  • -- (Декремент): Уменьшает переменную на 1.
int likes = 0;
likes++; // Теперь likes = 1
likes--; // Теперь likes = 0
Постфиксная и префиксная формы

Здесь кроется популярный вопрос на собеседованиях. Операторы можно ставить до переменной (++a) и после (a++).

  1. Постфиксная форма (a++): Сначала используем старое значение переменной в выражении, а потом увеличиваем её.
  2. Префиксная форма (++a): Сначала увеличиваем переменную, а потом используем новое значение.
int x = 5;
int y = x++; // Сначала y присвоили 5, потом x стал 6
System.out.println(x); // 6
System.out.println(y); // 5

int a = 5;
int b = ++a; // Сначала a стал 6, потом b присвоили 6
System.out.println(a); // 6
System.out.println(b); // 6

Составные операторы присваивания

Еще один способ писать код короче. Если вы хотите изменить переменную, используя её текущее значение, можно объединить арифметику и присваивание.

Полная запись Сокращенная запись
a = a + 5; a += 5;
b = b - 2; b -= 2;
c = c * 3; c *= 3;
d = d / 4; d /= 4;

Операции сравнения

Чтобы программа могла выбирать путь выполнения, ей нужно уметь сравнивать данные. Результатом любой операции сравнения всегда является логический тип (boolean) — то есть либо true (истина), либо false (ложь).

Список операторов:

  • > (Больше)
  • < (Меньше)
  • >= (Больше или равно)
  • <= (Меньше или равно)
  • == (Равно)
  • != (Не равно)
int age = 18;
boolean isAdult = age >= 18; // true
boolean isTeenager = age < 18; // false
boolean isZero = age == 0; // false

Опасная ловушка: == vs =

Новички часто путают эти два знака.

  • = — это оператор присваивания. «Возьми значение справа и положи в коробку слева».
  • == — это оператор сравнения. «Проверь, равны ли эти значения».
int x = 5; // Присвоили 5
// if (x = 10) ... // ОШИБКА! Вы пытаетесь присвоить, а не сравнить.
if (x == 10) ... // Правильно. Проверяем, равен ли x десяти.

Сравнение строк

Помните, мы говорили, что String — это не примитив, а объект? Оператор == сравнивает ссылки на объекты (адреса в памяти), а не их содержимое.

Золотое правило: Никогда не сравнивайте строки через ==. Используйте метод .equals().

String pass1 = "password";
String pass2 = "password";
// pass1 == pass2 может вернуть false в некоторых случаях!

boolean isCorrect = pass1.equals(pass2); // Всегда правильно проверяет текст

Логические операторы

В жизни мы часто принимаем решения, основанные на нескольких условиях. «Я пойду гулять, ЕСЛИ погода хорошая И у меня есть время». Или: «Я куплю этот телефон, ЕСЛИ он дешевый ИЛИ если мне дадут премию».

В Java для этого существуют логические операторы. Они работают с булевыми значениями.

1. Логическое И (AND) — &&

Результат истинен только тогда, когда оба условия истинны.

Математическая запись:

ABA \land B

Где AA — первое условие, BB — второе условие, а символ \land обозначает конъюнкцию (логическое И).

Условие A Условие B Результат A && B
false false false
false true false
true false false
true true true

Пример:

int battery = 50;
boolean hasWifi = true;

// Скачиваем обновление, если есть заряд И есть вайфай
boolean canDownload = (battery > 20) && hasWifi;

2. Логическое ИЛИ (OR) — ||

Результат истинен, если хотя бы одно из условий истинно.

Математическая запись:

ABA \lor B

Где AA — первое условие, BB — второе условие, а символ \lor обозначает дизъюнкцию (логическое ИЛИ).

| Условие A | Условие B | Результат A || B | | :--- | :--- | :--- | | false | false | false | | false | true | true | | true | false | true | | true | true | true |

Пример:

boolean isWeekend = true;
boolean isHoliday = false;

// Отдыхаем, если выходной ИЛИ праздник
boolean canRest = isWeekend || isHoliday; // true

3. Логическое НЕ (NOT) — !

Этот оператор инвертирует значение. Он превращает true в false и наоборот.

Математическая запись:

¬A\neg A

Где AA — условие, а символ ¬\neg обозначает отрицание.

boolean isRainy = true;
boolean isSunny = !isRainy; // false

«Ленивые» вычисления (Short-circuit evaluation)

Java — умный язык. Рассмотрим выражение:

if (false && (очень_сложное_вычисление)) { ... }

Java видит первый операнд false и оператор &&. Она знает, что для && нужно, чтобы оба были true. Раз первый уже false, результат всего выражения точно будет false. Поэтому Java не будет выполнять вторую часть выражения. Это экономит ресурсы и защищает от ошибок.

То же самое с ||: если первая часть true, то результат точно true, и вторая часть не проверяется.

Приоритет операций

Как и в математике, в Java есть порядок действий. Умножение выполняется раньше сложения.

Пример:

int x = 2 + 2 * 2;
System.out.println(x); // Выведет 6, а не 8

Упрощенная таблица приоритетов (от высшего к низшему):

  1. Постфиксные инкременты (a++, a--)
  2. Префиксные инкременты и унарные минусы (++a, --a, !, -)
  3. Умножение, деление, остаток (*, /, %)
  4. Сложение и вычитание (+, -)
  5. Сравнение (>, <, ==)
  6. Логическое И (&&)
  7. Логическое ИЛИ (||)
  8. Присваивание (=, +=)

Совет: Не заставляйте себя и коллег учить эту таблицу наизусть. Если сомневаетесь — ставьте скобки (). Код (2 + 2) * 2 читается гораздо проще и работает предсказуемо.

Практический пример: Високосный год

Давайте объединим арифметику и логику, чтобы решить классическую задачу: определить, является ли год високосным.

Правило:

  1. Год делится на 4 без остатка.
  2. НО если год делится на 100, он не високосный.
  3. ОДНАКО если год делится на 400, он все-таки високосный.
int year = 2024;

boolean isLeap = (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);

System.out.println("Год " + year + " високосный? " + isLeap);

Разберем логику:

  • year % 4 == 0: Проверяем делимость на 4.
  • &&: И при этом должно выполняться сложное условие в скобках.
  • year % 100 != 0: Год не должен быть вековым (1900, 1800).
  • ||: ИЛИ
  • year % 400 == 0: Если он делится на 400 (2000), то это исключение из исключения.

Заключение

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

В следующей статье мы перейдем к одной из самых захватывающих тем — управляющим конструкциям. Мы научимся писать код, который может ветвиться и выполнять разные действия в зависимости от ситуации, используя if, else и switch.

Управляющие конструкции: условные операторы if-else и switch

Управляющие конструкции: условные операторы if-else и switch

Добро пожаловать на четвертую лекцию курса «Основы синтаксиса Java». В предыдущих статьях мы научились создавать переменные, выполнять арифметические действия и сравнивать значения. Мы узнали, что 5 > 3 — это true (правда), а 2 + 2 == 5 — это false (ложь).

Однако до этого момента наши программы были линейными, как рельсы трамвая. Они выполняли команды строго одну за другой, от первой до последней строки. Но реальная жизнь полна выбора. Если идет дождь, мы берем зонт. Если на светофоре красный, мы стоим. Если у пользователя правильный пароль, мы пускаем его в систему.

Сегодня мы научимся управлять потоком выполнения программы (Control Flow). Мы превратим наш код из прямых рельсов в разветвленную сеть дорог, используя условные операторы.

Оператор if: Если это правда, то...

Самая базовая конструкция в программировании — это оператор if (если). Он позволяет выполнить блок кода только в том случае, если определенное условие истинно.

Синтаксис выглядит так:

if (условие) {
    // Код, который выполнится, если условие true
}

Ключевое слово if говорит компьютеру: «Проверь то, что в круглых скобках». Если результат проверки — true, то программа заходит внутрь фигурных скобок. Если false — программа просто перепрыгивает этот блок и идет дальше.

Пример:

int age = 20;

if (age >= 18) {
    System.out.println("Доступ разрешен.");
}

System.out.println("Программа завершена.");

В данном случае переменная age равна 20. Условие 20 >= 18 истинно. Поэтому мы увидим в консоли обе фразы.

Блоки кода и область видимости

Обратите внимание на фигурные скобки {}. Они ограничивают блок кода. Если условие верно, выполняются все команды внутри этого блока. Если вы забудете поставить скобки, Java выполнит только первую команду после if, что часто приводит к ошибкам.

Оператор else: Или-или

Часто нам нужно не просто выполнить действие при успехе, но и предусмотреть альтернативный сценарий. Что делать, если условие ложно? Для этого существует ключевое слово else (иначе).

int battery = 10;

if (battery > 20) {
    System.out.println("Можно смотреть видео.");
} else {
    System.out.println("Включен режим энергосбережения.");
}

Здесь у программы есть развилка. Она пойдет либо по пути if, либо по пути else. Третьего не дано.

Цепочка else if: Множественный выбор

Жизнь редко бывает черно-белой. Иногда вариантов больше двух. Например, светофор: красный, желтый, зеленый. Для таких случаев мы используем конструкцию else if.

int score = 85;

if (score >= 90) {
    System.out.println("Оценка: A");
} else if (score >= 75) {
    System.out.println("Оценка: B");
} else if (score >= 50) {
    System.out.println("Оценка: C");
} else {
    System.out.println("Оценка: F (Не сдал)");
}

Как это работает:

  1. Java проверяет первое условие (score >= 90). Если оно верно, выполняется первый блок, и программа выходит из всей конструкции. Остальные условия даже не проверяются.
  2. Если первое условие ложно, проверяется второе (score >= 75).
  3. И так далее.
  4. Если ни одно из условий if или else if не подошло, выполняется блок else (если он есть).

Важно: Порядок условий имеет значение! Если бы мы сначала написали if (score >= 50), то число 90 тоже подошло бы под это условие, и программа выдала бы оценку "C", проигнорировав "A". Всегда начинайте проверки от более строгих к более общим.

Тернарный оператор

Иногда конструкция if-else занимает слишком много места для простой операции присваивания. Допустим, мы хотим рассчитать цену товара со скидкой. Если клиент постоянный, скидка есть, иначе — нет.

Математически итоговую цену можно выразить формулой:

Pfinal=Pbase(1d)P_{final} = P_{base} \cdot (1 - d)

Где PfinalP_{final} — итоговая цена, PbaseP_{base} — базовая цена товара, а dd — коэффициент скидки (например, 0.10.1 для 10%).

В коде это могло бы выглядеть так:

double price;
if (isVipClient) {
    price = 100 * 0.9;
} else {
    price = 100;
}

Java позволяет записать это в одну строку с помощью тернарного оператора. Это единственный оператор, который принимает три аргумента. Его синтаксис: условие ? значение_если_true : значение_если_false.

double price = isVipClient ? 90.0 : 100.0;

Читается это так: «Является ли клиент VIP? Если да, то цена 90, иначе 100».

Оператор switch: Выбор из меню

Представьте, что вы пишете бота, который реагирует на команды: "Start", "Stop", "Pause", "Exit". Использовать цепочку if-else здесь можно, но код будет выглядеть громоздко и его будет трудно читать.

Для ситуаций, когда мы сравниваем одну переменную с набором конкретных значений, лучше использовать оператор switch (переключатель).

int dayOfWeek = 3;

switch (dayOfWeek) {
    case 1:
        System.out.println("Понедельник");
        break;
    case 2:
        System.out.println("Вторник");
        break;
    case 3:
        System.out.println("Среда");
        break;
    default:
        System.out.println("Неверный день");
}

Разберем анатомию switch:

  1. switch (переменная): В скобках указывается переменная, значение которой мы проверяем. Это может быть число (byte, short, int, char), строка (String) или перечисление (Enum).
  2. case значение: Это метка. Если переменная равна этому значению, программа начинает выполнять код с этого места.
  3. break: Критически важная команда! Она прерывает выполнение switch. Без нее программа продолжит выполнять команды следующих case, игнорируя проверки.
  4. default: Аналог else. Этот блок выполняется, если ни один case не подошел.

Опасность пропущенного break

Что будет, если убрать break?

int day = 1;
switch (day) {
    case 1:
        System.out.println("Понедельник");
    case 2:
        System.out.println("Вторник");
        break;
}

Если day равен 1, программа зайдет в case 1, напечатает "Понедельник", а затем, так как ее никто не остановил, она "провалится" вниз и напечатает "Вторник", и только потом встретит break. Иногда это используют специально (например, чтобы выполнить одно действие для нескольких кейсов), но чаще всего это ошибка новичка.

Группировка кейсов

Если мы хотим одинаковую реакцию на разные значения, мы можем группировать case:

switch (dayOfWeek) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        System.out.println("Будний день");
        break;
    case 6:
    case 7:
        System.out.println("Выходной");
        break;
}

Что выбрать: if или switch?

  • Используйте if-else, когда:

    • Условия сложные (диапазоны, логические И/ИЛИ).
    • Пример: if (x > 0 && x < 10).
    • Проверяются разные переменные.
  • Используйте switch, когда:

    • Вы проверяете одну и ту же переменную на равенство конкретным значениям.
    • Вариантов выбора много (3 и более).
    • Код должен быть максимально читаемым, как меню.

Вложенные условия

Одни условия могут находиться внутри других. Это называется вложенностью (nesting).

if (isWeekend) {
    if (isGoodWeather) {
        System.out.println("Идем в парк");
    } else {
        System.out.println("Смотрим кино дома");
    }
} else {
    System.out.println("Идем на работу");
}

Хотя Java позволяет делать вложенность любой глубины, старайтесь не злоупотреблять этим. Код, который выглядит как "стрела" из-за множества отступов, очень сложно читать и поддерживать.

Заключение

Сегодня мы дали нашей программе возможность «думать» и выбирать путь. Мы изучили:

  1. if — для выполнения кода по условию.
  2. else — для альтернативного действия.
  3. else if — для выбора из нескольких вариантов.
  4. Тернарный оператор — для краткой записи простых условий.
  5. switch — для красивой обработки множества конкретных значений.

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

Циклы for и while, введение в одномерные массивы

Циклы for и while, введение в одномерные массивы

Добро пожаловать на пятую лекцию курса «Основы синтаксиса Java». В прошлый раз мы научили наши программы принимать решения с помощью if-else и switch. Теперь наш код может выбирать разные пути в зависимости от условий. Но что, если нам нужно выполнить одно и то же действие много раз?

Представьте, что вам нужно вывести фразу «Я люблю Java» 100 раз. Копировать строку System.out.println сто раз — это не путь программиста. А если нужно обработать миллион записей из базы данных? Здесь нам на помощь приходят циклы.

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

Цикл while: Пока условие истинно

Самый простой и интуитивно понятный цикл — это while (пока). Его логика проста: «Пока условие в скобках истинно (true), выполняй блок кода». Как только условие становится ложным (false), цикл прекращается.

Синтаксис:

while (условие) {
    // Код, который будет повторяться
}

Пример: Обратный отсчет

Давайте напишем программу, которая ведет обратный отсчет перед запуском ракеты.

int count = 5;

while (count > 0) {
    System.out.println("До старта: " + count);
    count--; // Уменьшаем счетчик на 1
}

System.out.println("Поехали!");

Разбор полетов:

  1. Сначала count равен 5. Условие 5 > 0 истинно. Мы печатаем текст и уменьшаем count до 4.
  2. Снова проверка: 4 > 0. Истинно. Печатаем, уменьшаем до 3.
  3. ... Процесс повторяется ...
  4. Когда count станет равен 0, условие 0 > 0 станет ложным (false). Программа выйдет из цикла и напечатает «Поехали!».

Осторожно: Бесконечный цикл

Самая частая ошибка новичков — забыть изменить переменную, которая участвует в условии. Если бы мы убрали строку count--, то count всегда оставался бы равным 5, условие 5 > 0 всегда было бы истинным, и программа печатала бы текст вечно (или пока вы принудительно её не остановите).

Цикл do-while: Сначала делай, потом думай

Иногда нам нужно, чтобы код выполнился хотя бы один раз, независимо от условия. Для этого существует цикл do-while.

int number = 10;

do {
    System.out.println("Число: " + number);
    number--;
} while (number > 100);

Обратите внимание: условие number > 100 заведомо ложно (10 не больше 100). Но так как проверка стоит в конце, программа сначала выведет «Число: 10», уменьшит его до 9, и только потом проверит условие и выйдет из цикла.

Цикл for: Классика программирования

Если вы заранее знаете, сколько раз нужно повторить действие (например, 10 раз или для каждого элемента списка), лучше всего использовать цикл for.

Его синтаксис выглядит сложнее, но он очень компактен:

for (инициализация; условие; шаг) {
    // Тело цикла
}

Разберем три части в круглых скобках:

  1. Инициализация: Выполняется один раз в самом начале. Обычно здесь мы создаем переменную-счетчик (например, int i = 0).
  2. Условие: Проверяется перед каждой итерацией. Если true — идем внутрь, если false — выходим.
  3. Шаг (Итерация): Выполняется после каждого выполнения тела цикла. Обычно здесь мы увеличиваем счетчик (i++).

Пример: Сумма чисел

Допустим, нам нужно посчитать сумму всех чисел от 1 до 5. В математике это записывается с помощью знака суммы (сигма):

S=i=15i=1+2+3+4+5S = \sum_{i=1}^{5} i = 1 + 2 + 3 + 4 + 5

Где SS — итоговая сумма, ii — переменная счетчика, которая меняется от 1 до 5, а знак \sum обозначает операцию суммирования.

Реализуем эту формулу в коде:

int sum = 0;

for (int i = 1; i <= 5; i++) {
    sum = sum + i;
    System.out.println("Текущая сумма: " + sum);
}

Как это работает пошагово:

Шаг i Условие (i <= 5) Действие (sum += i) Новое i (i++)
1 1 true sum = 0 + 1 = 1 2
2 2 true sum = 1 + 2 = 3 3
3 3 true sum = 3 + 3 = 6 4
4 4 true sum = 6 + 4 = 10 5
5 5 true sum = 10 + 5 = 15 6
6 6 false Выход из цикла -

Операторы break и continue

Иногда нам нужно вмешаться в стандартный ход цикла.

  • break — немедленно прерывает выполнение цикла и выходит из него.
  • continue — пропускает оставшуюся часть кода в текущей итерации и переходит к следующей (к шагу изменения счетчика).
for (int i = 0; i < 10; i++) {
    if (i == 3) {
        continue; // Пропустит число 3
    }
    if (i == 6) {
        break; // Остановится полностью на числе 6
    }
    System.out.print(i + " ");
}
// Вывод: 0 1 2 4 5

Введение в массивы

До сих пор мы хранили данные в отдельных переменных: int a = 5;, int b = 10;. Но что, если нам нужно сохранить оценки 30 учеников или температуру за каждый день года? Создавать 365 переменных (temp1, temp2...) — безумие.

Для этого существуют массивы.

Массив — это контейнер, который хранит фиксированное количество значений одного типа.

Создание массива

В Java массив создается в два этапа (как и переменные, их можно объединить):

// 1. Объявление переменной массива (мы говорим, что numbers будет массивом int)
int[] numbers;

// 2. Выделение памяти (создаем массив на 5 ячеек)
numbers = new int[5];

// Или в одну строку:
int[] grades = new int[10];

Ключевое слово new здесь очень важно. Оно говорит Java: «Выдели в памяти место под 10 целых чисел».

Индексы: Считаем с нуля

Это самое важное правило, которое нужно запомнить навсегда: нумерация элементов в массиве начинается с 0.

Если мы создали массив на 5 элементов int[] arr = new int[5], то у нас есть ячейки с индексами: 0, 1, 2, 3, 4.

Индекса 5 не существует! Попытка обратиться к arr[5] вызовет ошибку ArrayIndexOutOfBoundsException (выход за пределы массива).

Работа с элементами

Чтобы положить значение в ящик или взять его оттуда, мы используем квадратные скобки [].

int[] box = new int[3];

box[0] = 10; // Положили 10 в первую ячейку
box[1] = 20; // Положили 20 во вторую
box[2] = 30; // Положили 30 в третью

System.out.println(box[0]); // Выведет 10
System.out.println(box[0] + box[2]); // Выведет 40

Длина массива

У каждого массива есть свойство length, которое хранит его размер.

System.out.println(box.length); // Выведет 3

Союз циклов и массивов

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

Заполнение массива

Давайте заполним массив числами от 0 до 9:

int[] data = new int[10];

for (int i = 0; i < data.length; i++) {
    data[i] = i * 10;
}
// Теперь в массиве: {0, 10, 20, 30, 40, 50, 60, 70, 80, 90}

Обратите внимание на условие i < data.length. Мы используем строгое неравенство (<), потому что последний индекс всегда на единицу меньше длины (длина 10, последний индекс 9).

Цикл for-each (Улучшенный for)

Если вам не нужен индекс (порядковый номер), а нужно просто перебрать все элементы подряд, в Java есть упрощенная версия цикла for.

int[] prices = {100, 200, 300};

// Читается как: "Для каждой цены (price) в массиве prices"
for (int price : prices) {
    System.out.println("Цена: " + price);
}

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

Итоги

Сегодня мы сделали огромный шаг вперед. Теперь вы можете:

  1. Использовать while и do-while для циклов с неизвестным числом повторений.
  2. Использовать for для счетчиков и перебора.
  3. Управлять потоком с помощью break и continue.
  4. Создавать массивы и хранить в них наборы данных.
  5. Обрабатывать массивы с помощью циклов.

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