From 231a37be9ed6fba74bfc4f03d7736fa4b69a1eac Mon Sep 17 00:00:00 2001 From: me Date: Mon, 2 Feb 2026 21:50:41 +0500 Subject: [PATCH] add notes for lecture 2 --- lectures/README.md | 1180 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1180 insertions(+) diff --git a/lectures/README.md b/lectures/README.md index 2bf3bc3..958360a 100644 --- a/lectures/README.md +++ b/lectures/README.md @@ -1,3 +1,1183 @@ +--- +gitea: none +allow-toc: true +--- + +# Конспект лекции 2: Массивы и ссылки +**Преподаватель:** Георгий Корнеев +**Курс:** Введение в программирование (Java) + +--- + +## Содержание +1. [Одномерные массивы](#1-одномерные-массивы) +2. [Многомерные массивы](#2-многомерные-массивы) +3. [Ссылки на массивы](#3-ссылки-на-массивы) +4. [Полные имена классов](#4-полные-имена-классов) +5. [Класс Scanner](#5-класс-scanner) +6. [Домашнее задание](#6-домашнее-задание) + +--- + +## 1. Одномерные массивы + +### 1.1. Типы данных в Java (повторение) + +**Классификация типов:** +``` +Типы данных +├── Примитивные (primitive) +│ ├── int, long +│ ├── char +│ ├── boolean +│ └── double, float +└── Ссылочные (reference) + ├── String + ├── Массивы + └── Объекты классов +``` + +⚠️ **Важно:** Массивы — это ссылочные типы! + +--- + +### 1.2. Объявление массивов + +#### Синтаксис объявления +```java +int[] ints; // Массив целых чисел +double[] doubles; // Массив вещественных чисел +boolean[] booleans; // Массив булевых значений +String[] strings; // Массив строк +char[] chars; // Массив символов +long[] longs; // Массив длинных целых +``` + +**Важные особенности:** +- Квадратные скобки `[]` указывают на тип "массив" +- Можно создавать массивы любых типов (примитивных и ссылочных) + +--- + +### 1.3. Создание массивов + +#### Способ 1: Указание размера +```java +ints = new int[10]; // Массив из 10 элементов +doubles = new double[20]; // Массив из 20 элементов +booleans = new boolean[30]; +strings = new String[40]; +chars = new char[5]; +longs = new long[3]; +``` + +#### Способ 2: Инициализация значениями +```java +ints = new int[]{1, 2, 3}; +doubles = new double[]{1.5}; +booleans = new boolean[]{true, false}; +strings = new String[]{"a", "b", "c"}; +``` + +#### Способ 3: Сокращённая инициализация (при объявлении) +```java +int[] ints = {1, 2, 3}; +String[] strings = {"hello", "world", "array"}; +``` + +⚠️ **Нельзя комбинировать:** `new int[5]{1, 2, 3, 4, 5}` — **НЕ компилируется!** + +--- + +### 1.4. Длина массива + +```java +int[] array = new int[10]; +System.out.println(array.length); // 10 (поле, НЕ метод!) +``` + +**Важно:** +- `length` — это **поле** (property), не метод +- Пишется **без скобок**: `array.length`, а не `array.length()` + +--- + +### 1.5. Значения по умолчанию + +При создании массива с указанием только размера элементы инициализируются значениями по умолчанию: + +| Тип | Значение по умолчанию | +|-----|----------------------| +| `int`, `long` | `0` | +| `double`, `float` | `0.0` | +| `boolean` | `false` | +| `char` | `'\0'` (символ с кодом 0) | +| Ссылочные типы (`String`, массивы) | `null` | + +```java +int[] ints = new int[10]; +System.out.println(ints[0]); // 0 + +boolean[] booleans = new boolean[10]; +System.out.println(booleans[0]); // false + +String[] strings = new String[10]; +System.out.println(strings[0]); // null +``` + +--- + +### 1.6. Доступ к элементам массива + +```java +int[] array = {1, 2, 3, 4, 5}; + +// Чтение +int first = array[0]; // 1 (нумерация с 0!) +int last = array[4]; // 5 + +// Запись +array[0] = 10; +array[2] = 30; + +// Результат: {10, 2, 30, 4, 5} +``` + +**Важно:** Индексация начинается с **0**! + +--- + +### 1.7. Ошибки при работе с массивами + +#### Отрицательная длина +```java +int[] array = new int[-5]; +// Исключение: NegativeArraySizeException +``` + +#### Выход за границы +```java +int[] array = new int[3]; +System.out.println(array[5]); +// Исключение: ArrayIndexOutOfBoundsException +``` + +#### Обращение к null +```java +int[] array = null; +System.out.println(array.length); +// Исключение: NullPointerException +``` + +--- + +### 1.8. Итерация по массивам + +#### Цикл for (с индексом) +```java +int[] ints = {1, 2, 3, 4, 5}; + +// i — это индекс +for (int i = 0; i < ints.length; i++) { + System.out.println(ints[i]); +} +``` + +**Когда использовать:** +- Нужен индекс элемента +- Нужен доступ на запись +- Нужна итерация с шагом (не по порядку) + +#### Цикл for-each (без индекса) +```java +int[] ints = {1, 2, 3, 4, 5}; + +// i — это значение элемента +for (int i : ints) { + System.out.println(i); +} +``` + +**Когда использовать:** +- Нужно только читать значения +- Итерация всегда последовательная +- Индекс не нужен + +**Преимущества for-each:** +- Более читаемый код +- Меньше ошибок (нет индексов) +- Работает с любыми коллекциями + +--- + +### 1.9. Максимальная длина массива + +```java +// Максимальное значение int +int maxSize = Integer.MAX_VALUE; // 2,147,483,647 + +// НО! Массив такой длины создать НЕЛЬЗЯ +int[] huge = new int[Integer.MAX_VALUE]; +// Исключение: OutOfMemoryError +``` + +**Ограничения:** +- Длина массива имеет тип `int` +- Физически ограничено доступной памятью +- JVM имеет лимиты на размер heap (куча) + +**Пример работы с памятью:** +```java +// Настройка heap для JVM +// java -Xmx16G MyProgram — выделить 16 GB +// java -Xmx1G MyProgram — выделить 1 GB + +// Создание большого массива +int[] array = new int[100_000_000]; // 100 млн элементов +// Занимает: 100,000,000 × 4 bytes = ~400 MB +``` + +--- + +### 1.10. Динамический размер массива + +Размер может определяться во время выполнения: + +```java +public static void main(String[] args) { + // Первый аргумент командной строки + int size = Integer.parseInt(args[0]); + + // Создаём массив динамического размера + int[] array = new int[size]; + + System.out.println("Создан массив длины: " + array.length); +} +``` + +```bash +# Запуск программы +java MyProgram 123 +# Вывод: Создан массив длины: 123 +``` + +--- + +## 2. Многомерные массивы + +### 2.1. Концепция многомерных массивов + +**Важная идея:** В Java многомерные массивы — это **массивы массивов**! + +``` +Двумерный массив: +int[][] matrix - это массив, каждый элемент которого — массив int[] + +Трёхмерный массив: +int[][][] cube - это массив, каждый элемент которого — массив int[][] +``` + +--- + +### 2.2. Объявление многомерных массивов + +```java +int[][] ints2d; // Двумерный массив +int[][][] ints3d; // Трёхмерный массив +String[][] strings2d; // Двумерный массив строк +``` + +--- + +### 2.3. Создание многомерных массивов + +#### Полное создание (прямоугольный массив) +```java +// Матрица 10×20 (10 строк, 20 столбцов) +int[][] matrix = new int[10][20]; + +// Куб 10×20×30 +int[][][] cube = new int[10][20][30]; + +System.out.println(matrix[0]); // [I@... (ссылка на массив int[]) +System.out.println(cube[0]); // [[I@... (ссылка на int[][]) +``` + +#### Частичное создание +```java +// Создаём только первое измерение +int[][] matrix = new int[10][]; +int[][][] cube = new int[10][][]; + +System.out.println(matrix[0]); // null (элементы не созданы!) +System.out.println(cube[0]); // null +``` + +**Использование:** +```java +int[][] matrix = new int[10][]; + +// Заполняем вручную +for (int i = 0; i < matrix.length; i++) { + matrix[i] = new int[i]; // Каждая строка своей длины! +} +``` + +--- + +### 2.4. Непрямоугольные массивы + +Java позволяет создавать **"рваные" массивы** (jagged arrays) — массивы, где строки имеют разную длину: + +```java +// Создание непрямоугольного массива +int[][] jagged = new int[3][]; +jagged[0] = new int[5]; // Первая строка — 5 элементов +jagged[1] = new int[2]; // Вторая строка — 2 элемента +jagged[2] = new int[7]; // Третья строка — 7 элементов + +// Проверка длин +for (int[] row : jagged) { + System.out.println(row.length); // 5, 2, 7 +} +``` + +#### Инициализация непрямоугольного массива +```java +int[][] jagged = new int[][]{ + {1, 2, 3}, // Строка из 3 элементов + {4, 5}, // Строка из 2 элементов + {6, 7, 8, 9}, // Строка из 4 элементов + null // Пустая строка (null) +}; + +System.out.println(jagged.length); // 4 (количество строк) +System.out.println(jagged[0].length); // 3 +System.out.println(jagged[1].length); // 2 +System.out.println(jagged[2].length); // 4 +System.out.println(jagged[3]); // null +``` + +⚠️ **Внимание:** `jagged[3].length` вызовет `NullPointerException`! + +--- + +### 2.5. Работа с двумерными массивами + +#### Итерация по всем элементам +```java +int[][] matrix = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +// Вложенные циклы for +for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[i].length; j++) { + System.out.print(matrix[i][j] + " "); + } + System.out.println(); +} + +// Вложенные циклы for-each +for (int[] row : matrix) { + for (int element : row) { + System.out.print(element + " "); + } + System.out.println(); +} +``` + +--- + +### 2.6. Значения по умолчанию в многомерных массивах + +```java +int[][] matrix = new int[3][4]; + +// Все элементы инициализированы нулями +System.out.println(matrix[0][0]); // 0 + +String[][] strings = new String[3][4]; + +// Все элементы равны null +System.out.println(strings[0][0]); // null +``` + +--- + +## 3. Ссылки на массивы + +### 3.1. Массивы как ссылочный тип + +**Ключевая концепция:** Переменная массива хранит не сам массив, а **ссылку** на него в памяти. + +```java +int[] a = new int[10]; // a содержит ссылку на массив +``` + +``` +Память: +┌─────────┐ ┌───────────────┐ +│ a │───────>│ [0,0,0,...,0] │ +└─────────┘ └───────────────┘ +переменная массив в heap +``` + +--- + +### 3.2. Копирование ссылок + +```java +int[] a = new int[10]; +int[] b = a; // b указывает на ТОТ ЖЕ массив! + +a[1] = 10; +System.out.println(a[1] + " " + b[1]); // 10 10 + +System.out.println(a == b); // true (одна и та же ссылка) +``` + +``` +Память: +┌─────────┐ ┌───────────────┐ +│ a │───────>│ [0,10,0,...,0]│ +└─────────┘ ┌──>└───────────────┘ +┌─────────┐ │ +│ b │────┘ +└─────────┘ +``` + +--- + +### 3.3. Переприсваивание ссылок + +```java +int[] a = new int[10]; +int[] b = a; + +a = new int[10]; // a теперь указывает на НОВЫЙ массив! + +a[1] = 20; +System.out.println(a[1] + " " + b[1]); // 20 10 + +System.out.println(a == b); // false (разные массивы) +``` + +``` +До: a и b указывают на один массив +┌─────┐ ┌───────────────┐ +│ a │───>│ [0,0,0,...,0] │ +└─────┘ ┌─>└───────────────┘ +┌─────┐ │ +│ b │─┘ +└─────┘ + +После: a указывает на новый массив +┌─────┐ ┌───────────────┐ +│ a │───>│ [0,20,0,...,0]│ +└─────┘ └───────────────┘ +┌─────┐ ┌───────────────┐ +│ b │───>│ [0,0,0,...,0] │ +└─────┘ └───────────────┘ +``` + +--- + +### 3.4. Передача массивов в функции + +#### Изменение элементов массива +```java +void fill(int[] ints, int value) { + for (int i = 0; i < ints.length; i++) { + ints[i] = value; + } +} + +// Использование +int[] array = new int[3]; +fill(array, 100); +System.out.println(Arrays.toString(array)); // [100, 100, 100] +``` + +✅ **Изменения видны снаружи** — мы меняем элементы по ссылке! + +--- + +#### Переприсваивание параметра (НЕ работает!) +```java +void referenceAsValue(int[] ints) { + ints = new int[0]; // Локальное изменение параметра +} + +// Использование +int[] a = new int[10]; +int[] b = a; +referenceAsValue(a); +System.out.println(a == b); // true (массив НЕ изменился!) +``` + +❌ **Переприсваивание НЕ видно снаружи** — параметры передаются по значению! + +**Почему так происходит:** +``` +При вызове функции: +1. Копируется ССЫЛКА (не сам массив) +2. Локальный параметр указывает на тот же массив +3. Переприсваивание меняет только локальную переменную +4. Исходная переменная остаётся без изменений +``` + +--- + +### 3.5. Возврат массива из функции + +```java +int[] create(int length, int value) { + int[] ints = new int[length]; + for (int i = 0; i < ints.length; i++) { + ints[i] = value; + } + return ints; // Возвращаем ссылку на созданный массив +} + +// Использование +int[] array = create(3, 123); +System.out.println(Arrays.toString(array)); // [123, 123, 123] +``` + +✅ **Массив создаётся в heap** и продолжает существовать после выхода из функции! + +--- + +### 3.6. Сборка мусора (Garbage Collection) + +Java автоматически освобождает память от неиспользуемых объектов: + +```java +int[] a = new int[1_000_000]; + +// Создаём 10 миллионов массивов +for (int i = 0; i < 10_000_000; i++) { + a = new int[1_000_000]; // Старый массив становится мусором +} + +System.out.println("ok"); +// Программа работает! Сборщик мусора освобождает память +``` + +**Как это работает:** +1. Когда на объект не осталось ссылок, он становится "мусором" +2. Сборщик мусора периодически удаляет такие объекты +3. Память освобождается автоматически + +--- + +### 3.7. Копирование массивов + +#### Проблема с присваиванием +```java +int[] a = {1, 2, 3}; +int[] b = a; // Это НЕ копирование, это копирование ссылки! + +a[0] = 100; +System.out.println(b[0]); // 100 (изменили оба массива!) +``` + +#### Правильное копирование: System.arraycopy() +```java +int[] source = {0, 10, 20, 30, 40, 50}; +int[] dest = new int[5]; + +// System.arraycopy(откуда, откуда_индекс, куда, куда_индекс, сколько) +System.arraycopy(source, 2, dest, 1, 3); + +System.out.println(Arrays.toString(dest)); // [-1, 20, 30, 40, -1] +``` + +**Параметры:** +- `source` — исходный массив +- `2` — начальный индекс в источнике +- `dest` — массив назначения +- `1` — начальный индекс в назначении +- `3` — количество копируемых элементов + +**Схема:** +``` +source: [0, 10, 20, 30, 40, 50] + ^ ^ ^ + | | | + └───┼───┘ + ↓ +dest: [-1, 20, 30, 40, -1] + ^ ^ ^ ^ ^ +``` + +--- + +### 3.8. Особенности System.arraycopy() + +#### Корректная работа с перекрывающимися областями +```java +int[] array = {1, 2, 3, 4, 5}; + +// Копирование внутри одного массива (вправо) +System.arraycopy(array, 0, array, 2, 3); +// Результат: [1, 2, 1, 2, 3] + +// Копирование внутри одного массива (влево) +int[] array2 = {1, 2, 3, 4, 5}; +System.arraycopy(array2, 2, array2, 0, 3); +// Результат: [3, 4, 5, 4, 5] +``` + +✅ `System.arraycopy()` корректно обрабатывает перекрытия (использует временный буфер при необходимости) + +--- + +## 4. Полные имена классов + +### 4.1. Пакеты в Java + +Java использует **иерархическую систему пакетов** для организации классов: + +``` +java (корневой пакет) +├── lang (фундаментальные классы) +│ ├── String +│ ├── System +│ ├── Integer +│ ├── Object +│ └── Math +├── util (вспомогательные утилиты) +│ ├── Arrays +│ ├── Scanner +│ ├── ArrayList +│ └── zip (подпакет для сжатия) +│ ├── ZipFile +│ └── GZIPInputStream +└── io (ввод-вывод) + ├── File + ├── InputStream + └── OutputStream + +javax (дополнительные пакеты) +└── crypto (криптография) +``` + +--- + +### 4.2. Полные имена классов + +**Полное имя** = путь через пакеты + имя класса + +```java +// Полное имя класса System +java.lang.System + +// Полное имя класса Arrays +java.util.Arrays + +// Полное имя класса Scanner +java.util.Scanner +``` + +#### Использование полных имён +```java +// Можно использовать полное имя везде +java.util.Arrays.toString(array); +java.lang.System.out.println("Hello"); +java.lang.Integer.parseInt("123"); +``` + +--- + +### 4.3. Оператор import + +Чтобы не писать полные имена постоянно, используется `import`: + +```java +import java.util.Arrays; +import java.util.Scanner; +import java.lang.Integer; + +// Теперь можно использовать короткие имена +Arrays.toString(array); +Scanner scanner = new Scanner(System.in); +Integer.parseInt("123"); +``` + +#### Импорт всех классов из пакета +```java +import java.util.*; // Импортирует все классы из java.util + +Arrays.toString(array); // Работает +Scanner scanner = ...; // Работает +``` + +--- + +### 4.4. Неявный импорт java.lang + +**Важно:** Пакет `java.lang` **импортируется автоматически**! + +```java +// Эта строка присутствует неявно в каждой программе: +import java.lang.*; + +// Поэтому эти классы доступны без import: +String s = "hello"; +System.out.println(s); +Integer.parseInt("123"); +Math.sqrt(25); +``` + +--- + +### 4.5. Класс Arrays + +Класс `java.util.Arrays` содержит полезные методы для работы с массивами: + +```java +import java.util.Arrays; + +int[] array = {3, 1, 4, 1, 5}; + +// Преобразование в строку +String str = Arrays.toString(array); +System.out.println(str); // [3, 1, 4, 1, 5] + +// Заполнение массива +Arrays.fill(array, 7); +System.out.println(Arrays.toString(array)); // [7, 7, 7, 7, 7] + +// Сортировка +int[] data = {5, 2, 8, 1, 9}; +Arrays.sort(data); +System.out.println(Arrays.toString(data)); // [1, 2, 5, 8, 9] + +// Копирование +int[] copy = Arrays.copyOf(data, data.length); +``` + +--- + +### 4.6. Вывод массивов + +```java +int[] array = {0, 10, 20, 30}; + +// Прямой вывод (плохо!) +System.out.println(array); // [I@3834d63f (адрес в памяти) + +// Правильный вывод +System.out.println(Arrays.toString(array)); // [0, 10, 20, 30] +``` + +**Почему так происходит:** +- Массивы — ссылочный тип +- При прямом выводе печатается представление ссылки +- `[I@...` означает "массив int" + хеш-код + +--- + +## 5. Класс Scanner + +### 5.1. Назначение класса Scanner + +**Scanner** — класс для удобного чтения данных из различных источников: +- Стандартный ввод (консоль) +- Файлы +- Строки +- Потоки данных + +```java +import java.util.Scanner; +``` + +--- + +### 5.2. Создание Scanner для стандартного ввода + +```java +Scanner scanner = new Scanner(System.in); +``` + +**Параметры:** +- `System.in` — стандартный поток ввода (stdin) +- Можно также использовать `File`, `String`, `InputStream` и др. + +--- + +### 5.3. Основные методы Scanner + +#### Чтение различных типов данных +```java +Scanner scanner = new Scanner(System.in); + +// Чтение целого числа +int number = scanner.nextInt(); + +// Чтение вещественного числа +double value = scanner.nextDouble(); + +// Чтение строки (до пробела) +String word = scanner.next(); + +// Чтение целой строки (до конца строки) +String line = scanner.nextLine(); + +// Чтение символа (нет прямого метода, используем next()) +char ch = scanner.next().charAt(0); +``` + +--- + +### 5.4. Проверка наличия данных + +```java +Scanner scanner = new Scanner(System.in); + +// Проверка наличия следующего токена +while (scanner.hasNext()) { + String word = scanner.next(); + System.out.println(word); +} + +// Проверка наличия целого числа +while (scanner.hasNextInt()) { + int number = scanner.nextInt(); + System.out.println(number + 1); +} + +// Проверка наличия строки +while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + System.out.println(line); +} +``` + +--- + +### 5.5. Пример: сумма чисел +```java +import java.util.Scanner; + +public class SumExample { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.print("Введите два числа: "); + int a = scanner.nextInt(); + int b = scanner.nextInt(); + + System.out.println("Сумма: " + (a + b)); + } +} +``` + +**Запуск:** +``` +Введите два числа: 10 20 +Сумма: 30 +``` + +--- + +### 5.6. Пример: чтение всех чисел и увеличение на 1 + +```java +Scanner scanner = new Scanner(System.in); + +// Читаем и увеличиваем пока есть числа +while (scanner.hasNextInt()) { + int number = scanner.nextInt(); + System.out.println(number + 1); +} +``` + +**Ввод:** +``` +1 2 3 +4 5 +``` + +**Вывод:** +``` +2 +3 +4 +5 +6 +``` + +--- + +### 5.7. Работа с пробелами и переводами строк + +Scanner **автоматически пропускает** пробельные символы (пробелы, табуляции, переводы строк): + +```java +Scanner scanner = new Scanner(System.in); + +// Ввод: " hello world " +String s1 = scanner.next(); // "hello" +String s2 = scanner.next(); // "world" +``` + +**Для чтения целых строк:** +```java +String line = scanner.nextLine(); // Читает ВСЁ до конца строки +``` + +--- + +### 5.8. Важные замечания + +1. **Scanner читает из потока последовательно** — прочитанные данные нельзя "вернуть обратно" +2. **Разделители по умолчанию** — пробелы, табуляции, переводы строк +3. **Можно настроить разделители** через метод `useDelimiter()` +4. **Нет прямого способа прочитать char** — используйте `scanner.next().charAt(0)` + +--- + +## 6. Домашнее задание + +### 6.1. Задание: Класс Reverse + +**Описание:** Разработать класс `Reverse`, который читает числа из стандартного ввода и выводит их в обратном порядке. + +**Требования:** +1. Числа могут быть на нескольких строках +2. В каждой строке может быть несколько чисел +3. Нужно развернуть **порядок строк** +4. Нужно развернуть **порядок чисел в каждой строке** +5. Числа разделены пробелами +6. Все числа помещаются в тип `int` +7. Использовать класс `Scanner` + +--- + +### 6.2. Примеры + +#### Пример 1 +**Ввод:** +``` +1 2 +3 +``` + +**Вывод:** +``` +3 +2 1 +``` + +--- + +#### Пример 2 +**Ввод:** +``` +3 +1 2 +``` + +**Вывод:** +``` +2 1 +3 +``` + +--- + +#### Пример 3: Отрицательные числа +**Ввод:** +``` +-1 -2 -3 +4 5 +``` + +**Вывод:** +``` +5 4 +-3 -2 -1 +``` + +--- + +#### Пример 4: Пустые строки +**Ввод:** +``` +1 2 + +3 4 +``` + +**Вывод:** +``` +4 3 + +2 1 +``` + +**Важно:** Пустые строки сохраняются! + +--- + +#### Пример 5: Множественные пробелы +**Ввод:** +``` +1 2 3 +4 5 +``` + +**Вывод:** +``` +5 4 +3 2 1 +``` + +**Важно:** В выводе между числами **ровно один пробел**! + +--- + +#### Пример 6: Полный пример +**Ввод:** +``` +1 2 +3 4 + +5 6 +``` + +**Вывод:** +``` +6 5 + +4 3 +2 1 +``` + +--- + +### 6.3. Требования к реализации + +#### Эффективность +- ✅ Программа должна работать **эффективно по памяти** +- ✅ Программа должна работать **эффективно по времени** +- ⚠️ Подумайте, как хранить данные оптимально + +#### Что использовать +- ✅ Класс `Scanner` для чтения +- ✅ Массивы для хранения данных +- ✅ Любые конструкции из стандартной библиотеки Java + +#### Формат вывода +- Числа в строке разделены **одним пробелом** +- Каждая строка заканчивается переводом строки +- Пустые строки выводятся как есть + +--- + +### 6.4. Алгоритм решения (подсказки) + +**Этапы:** +1. **Чтение данных** + - Читать строку за строкой + - Для каждой строки читать все числа + - Сохранять в структуру данных (двумерный массив?) + +2. **Разворот** + - Развернуть порядок строк + - В каждой строке развернуть порядок чисел + +3. **Вывод** + - Вывести каждую строку + - Числа через один пробел + +**Вопросы для размышления:** +- Как хранить строки разной длины? (Непрямоугольный массив!) +- Как отличить пустую строку от конца ввода? +- Как эффективно развернуть массивы? + +--- + +## Резюме лекции + +### Ключевые концепции + +1. **Массивы — ссылочный тип** + - Хранят ссылку, а не данные напрямую + - Передача в функции = передача ссылки + - Присваивание = копирование ссылки + +2. **Многомерные массивы = массивы массивов** + - Могут быть непрямоугольными + - Каждое измерение — отдельный массив + +3. **Значения по умолчанию** + - Примитивы: `0`, `false`, `'\0'` + - Ссылочные типы: `null` + +4. **Пакеты и импорты** + - `java.lang.*` импортируется автоматически + - Остальные пакеты требуют `import` + - Полное имя = `пакет.класс` + +5. **Полезные классы** + - `Arrays` — работа с массивами + - `Scanner` — чтение данных + - `System` — системные операции + +--- + +### Важные методы и техники + +```java +// Работа с массивами +Arrays.toString(array) // Красивый вывод +Arrays.fill(array, value) // Заполнение +System.arraycopy(...) // Копирование + +// Чтение данных +Scanner scanner = new Scanner(System.in); +scanner.nextInt() // Прочитать число +scanner.next() // Прочитать слово +scanner.nextLine() // Прочитать строку +scanner.hasNext() // Проверить наличие данных +``` + +--- + +### Типичные ошибки и их решения + +| Ошибка | Причина | Решение | +|--------|---------|---------| +| `NullPointerException` | Обращение к null | Проверять на null | +| `ArrayIndexOutOfBoundsException` | Выход за границы | Проверять индексы | +| `NegativeArraySizeException` | Отрицательный размер | Валидировать размер | + +--- + +### Что дальше + +- Практика работы с массивами +- Выполнение домашнего задания Reverse +- Следующая тема: классы и объекты + +--- + +**Полезные ссылки:** +- [Java Arrays Tutorial](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html) +- [Java Arrays Documentation](https://docs.oracle.com/javase/specs/jls/se21/html/jls-10.html) +- [java.util.Arrays API](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Arrays.html) +- [java.util.Scanner API](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Scanner.html) + +--- + +**Удачи в выполнении домашнего задания! 🚀** + # Конспект лекции 1: Введение в программирование (Java) **Преподаватель:** Георгий Корнеев