1764 lines
53 KiB
Markdown
1764 lines
53 KiB
Markdown
---
|
||
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)
|
||
**Преподаватель:** Георгий Корнеев
|
||
|
||
---
|
||
|
||
## 1. Организационные вопросы
|
||
|
||
### 1.1. Контактная информация
|
||
- **Преподаватель:** Георгий Корнеев
|
||
- **Связь:**
|
||
- Основные вопросы → чат курса
|
||
- Сложные/долгие вопросы → email преподавателя
|
||
|
||
### 1.2. Структура курса
|
||
**Последовательность предметов:**
|
||
- 1 курс: Введение в программирование (Java)
|
||
- 2 курс 1 семестр: Парадигмы программирования
|
||
- 2 курс 2 семестр: Технологии Java
|
||
|
||
---
|
||
|
||
## 2. Организация учебного процесса
|
||
|
||
### 2.1. Структура занятий
|
||
|
||
#### Лекции
|
||
- Теоретический материал
|
||
- Live coding
|
||
- Демонстрации примеров
|
||
|
||
#### Домашние задания
|
||
- Выдаются после каждой лекции
|
||
- Срок выполнения: около недели (чуть меньше, т.к. практики перед лекциями)
|
||
- Все последующие ДЗ (кроме первого) требуют самостоятельно написанного кода на Java
|
||
|
||
#### Практические занятия
|
||
- Сдача **модификации** домашнего задания (не самого ДЗ!)
|
||
- Модификация тесно связана с домашним заданием
|
||
- **Пример:** ДЗ - скомпилировать Hello World, практика - скомпилировать другую программу
|
||
|
||
---
|
||
|
||
## 3. Система оценивания
|
||
|
||
### 3.1. Версии домашних заданий
|
||
- **Простая версия** → НЕ нужно делать
|
||
- **Сложная версия** → ОБЯЗАТЕЛЬНО делать
|
||
|
||
### 3.2. Попытки сдачи
|
||
- **Количество попыток:** 3 (три вторника подряд)
|
||
- Если за 3 попытки не сдано → ДЗ не засчитывается
|
||
|
||
### 3.3. Система задержек (delay)
|
||
**Фиксируется момент ПЕРВОЙ демонстрации рабочей программы преподавателю:**
|
||
- Сдача в первую неделю → delay = 0
|
||
- Сдача во вторую неделю → delay = 1
|
||
- Сдача в третью неделю → delay = 2
|
||
|
||
⚠️ **Важно:** Задержка определяется моментом первой демонстрации работающей программы, а не финальной сдачи!
|
||
|
||
### 3.4. Система минусов
|
||
**Начисление минусов:**
|
||
- Преподаватель проверяет код
|
||
- За найденные проблемы назначаются минусы
|
||
- Минусы **накапливаются** при каждой попытке
|
||
|
||
**Пример расчёта:**
|
||
- 1 попытка: 3 минуса
|
||
- 2 попытка: 2 минуса
|
||
- 3 попытка: 0 минусов (успешно)
|
||
- **Итого:** 5 минусов, delay = 0 (т.к. начали с первой недели)
|
||
|
||
### 3.5. Бонусные баллы
|
||
|
||
#### Бонусы за скорость сдачи
|
||
- **Условие:** Первый студент, сдавший ДЗ преподавателю в первую неделю
|
||
- **Количество:** До 5 человек (по числу преподавателей)
|
||
|
||
#### Бонусы за найденные ошибки
|
||
- За обнаруженные ошибки и опечатки в материалах курса
|
||
- Сообщать в специальный раздел чата
|
||
|
||
---
|
||
|
||
## 4. Зачёт
|
||
|
||
### 4.1. Условия
|
||
- Проводится при неудовлетворительных баллах
|
||
- Если баллов достаточно → зачёт не обязателен
|
||
|
||
### 4.2. Варианты сдачи
|
||
- **Досрочная сдача:** конец декабря
|
||
- **Стандартная сдача:** во время сессии
|
||
|
||
---
|
||
|
||
## 5. Особенности первого домашнего задания
|
||
|
||
### 5.1. Уникальные условия
|
||
- Несложное (т.к. не было лекций)
|
||
- **Срок сдачи:** только первая практика
|
||
- Больше не принимается
|
||
|
||
---
|
||
|
||
## 6. Почему Java?
|
||
|
||
### 6.1. Популярность
|
||
- **Индекс TIOBE:** Java в топе популярных языков
|
||
- В плотной группе с C, C++, Python
|
||
- Python вырвался вперёд в последние 2-3 года
|
||
|
||
### 6.2. Преимущества Java
|
||
|
||
#### Простота и безопасность
|
||
- Достаточно простой язык
|
||
- Сложно создать код, который:
|
||
- Убьёт компьютер
|
||
- Приведёт к непредсказуемому поведению
|
||
- Не воспроизводится на других машинах
|
||
|
||
#### Содержательность
|
||
- Простой, но весьма содержательный язык
|
||
- Широкий спектр возможностей
|
||
|
||
#### Области применения
|
||
1. **Серверные приложения**
|
||
2. **Desktop-приложения**
|
||
3. **Android-разработка**
|
||
4. **JVM-языки** (Kotlin, Scala и др.)
|
||
|
||
---
|
||
|
||
## 7. Основы Java
|
||
|
||
### 7.1. Концепция Java
|
||
|
||
#### Виртуальная машина (JVM)
|
||
- Java компилируется не в машинный код, а в **байт-код**
|
||
- Байт-код исполняется на **виртуальной машине Java (JVM)**
|
||
- **Преимущество:** кроссплатформенность (Write Once, Run Anywhere)
|
||
|
||
#### Процесс выполнения программы
|
||
1. Написание кода на Java (.java файлы)
|
||
2. Компиляция в байт-код (.class файлы)
|
||
3. Выполнение на JVM
|
||
|
||
### 7.2. Установка и настройка
|
||
|
||
#### Java Development Kit (JDK)
|
||
- **Что включает:**
|
||
- Компилятор Java
|
||
- JVM
|
||
- Стандартная библиотека
|
||
- Инструменты разработки
|
||
|
||
#### Проверка установки
|
||
```bash
|
||
java -version # Проверка установленной версии JVM
|
||
javac -version # Проверка версии компилятора
|
||
```
|
||
|
||
### 7.3. Первая программа: Hello World
|
||
|
||
#### Структура программы
|
||
```java
|
||
public class HelloWorld {
|
||
public static void main(String[] args) {
|
||
System.out.println("Hello, World!");
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Ключевые элементы
|
||
- `public class HelloWorld` - объявление публичного класса
|
||
- Имя класса должно совпадать с именем файла
|
||
- `public static void main(String[] args)` - точка входа в программу
|
||
- `System.out.println()` - вывод в консоль
|
||
|
||
#### Компиляция и запуск
|
||
```bash
|
||
javac HelloWorld.java # Компиляция → создаёт HelloWorld.class
|
||
java HelloWorld # Запуск (БЕЗ расширения .class!)
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Основы синтаксиса Java
|
||
|
||
### 8.1. Типы данных
|
||
|
||
#### Примитивные типы
|
||
|
||
**Целочисленные:**
|
||
- `byte` - 8 бит (-128 до 127)
|
||
- `short` - 16 бит (-32768 до 32767)
|
||
- `int` - 32 бита (-2³¹ до 2³¹-1)
|
||
- `long` - 64 бита (-2⁶³ до 2⁶³-1)
|
||
|
||
**Вещественные:**
|
||
- `float` - 32 бита (одинарная точность)
|
||
- `double` - 64 бита (двойная точность)
|
||
|
||
**Другие:**
|
||
- `boolean` - true/false
|
||
- `char` - 16 бит (символ Unicode)
|
||
|
||
#### Ссылочные типы
|
||
- Строки: `String`
|
||
- Массивы
|
||
- Объекты классов
|
||
|
||
### 8.2. Переменные
|
||
|
||
#### Объявление и инициализация
|
||
```java
|
||
int x; // Объявление
|
||
x = 10; // Инициализация
|
||
int y = 20; // Объявление с инициализацией
|
||
```
|
||
|
||
#### Константы
|
||
```java
|
||
final int MAX_VALUE = 100; // Константа (нельзя изменить)
|
||
```
|
||
|
||
### 8.3. Операторы
|
||
|
||
#### Арифметические операторы
|
||
- `+` - сложение
|
||
- `-` - вычитание
|
||
- `*` - умножение
|
||
- `/` - деление
|
||
- `%` - остаток от деления
|
||
|
||
#### Операторы сравнения
|
||
- `==` - равно
|
||
- `!=` - не равно
|
||
- `>`, `<` - больше, меньше
|
||
- `>=`, `<=` - больше или равно, меньше или равно
|
||
|
||
#### Логические операторы
|
||
- `&&` - логическое И (AND)
|
||
- `||` - логическое ИЛИ (OR)
|
||
- `!` - логическое НЕ (NOT)
|
||
|
||
#### Операторы присваивания
|
||
- `=` - присваивание
|
||
- `+=`, `-=`, `*=`, `/=` - составное присваивание
|
||
|
||
### 8.4. Управляющие конструкции
|
||
|
||
#### Условный оператор if
|
||
```java
|
||
if (условие) {
|
||
// код
|
||
} else if (другое_условие) {
|
||
// код
|
||
} else {
|
||
// код
|
||
}
|
||
```
|
||
|
||
#### Оператор switch
|
||
```java
|
||
switch (переменная) {
|
||
case значение1:
|
||
// код
|
||
break;
|
||
case значение2:
|
||
// код
|
||
break;
|
||
default:
|
||
// код по умолчанию
|
||
}
|
||
```
|
||
|
||
#### Цикл while
|
||
```java
|
||
while (условие) {
|
||
// код
|
||
}
|
||
```
|
||
|
||
#### Цикл do-while
|
||
```java
|
||
do {
|
||
// код
|
||
} while (условие);
|
||
```
|
||
|
||
#### Цикл for
|
||
```java
|
||
for (инициализация; условие; инкремент) {
|
||
// код
|
||
}
|
||
|
||
// Пример:
|
||
for (int i = 0; i < 10; i++) {
|
||
System.out.println(i);
|
||
}
|
||
```
|
||
|
||
#### Цикл for-each
|
||
```java
|
||
for (тип элемент : коллекция) {
|
||
// код
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 9. Ввод и вывод
|
||
|
||
### 9.1. Вывод в консоль
|
||
```java
|
||
System.out.println("текст"); // Вывод с переводом строки
|
||
System.out.print("текст"); // Вывод без перевода строки
|
||
```
|
||
|
||
### 9.2. Ввод из консоли
|
||
```java
|
||
import java.util.Scanner;
|
||
|
||
Scanner scanner = new Scanner(System.in);
|
||
int number = scanner.nextInt(); // Чтение целого числа
|
||
String line = scanner.nextLine(); // Чтение строки
|
||
double d = scanner.nextDouble(); // Чтение вещественного числа
|
||
```
|
||
|
||
### 9.3. Работа с аргументами командной строки
|
||
```java
|
||
public static void main(String[] args) {
|
||
// args[0] - первый аргумент
|
||
// args[1] - второй аргумент
|
||
// args.length - количество аргументов
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Массивы
|
||
|
||
### 10.1. Одномерные массивы
|
||
|
||
#### Объявление и создание
|
||
```java
|
||
int[] array; // Объявление
|
||
array = new int[10]; // Создание массива на 10 элементов
|
||
int[] array2 = new int[5]; // Объявление с созданием
|
||
|
||
// Инициализация значениями
|
||
int[] array3 = {1, 2, 3, 4, 5};
|
||
```
|
||
|
||
#### Обращение к элементам
|
||
```java
|
||
array[0] = 10; // Присваивание
|
||
int x = array[0]; // Чтение
|
||
```
|
||
|
||
#### Длина массива
|
||
```java
|
||
int length = array.length; // Поле length (НЕ метод!)
|
||
```
|
||
|
||
### 10.2. Многомерные массивы
|
||
```java
|
||
int[][] matrix = new int[3][4]; // 3 строки, 4 столбца
|
||
int[][] matrix2 = {{1,2}, {3,4}, {5,6}};
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Строки (String)
|
||
|
||
### 11.1. Создание строк
|
||
```java
|
||
String s1 = "Hello";
|
||
String s2 = new String("World");
|
||
```
|
||
|
||
### 11.2. Основные методы
|
||
```java
|
||
int len = s.length(); // Длина строки
|
||
char ch = s.charAt(0); // Символ по индексу
|
||
String sub = s.substring(0, 5); // Подстрока
|
||
String upper = s.toUpperCase(); // В верхний регистр
|
||
String lower = s.toLowerCase(); // В нижний регистр
|
||
```
|
||
|
||
### 11.3. Конкатенация
|
||
```java
|
||
String result = s1 + s2;
|
||
String result2 = s1.concat(s2);
|
||
```
|
||
|
||
### 11.4. Особенности строк
|
||
- Строки в Java **неизменяемые** (immutable)
|
||
- Все операции создают новые строки
|
||
- Сравнение строк: использовать `equals()`, НЕ `==`
|
||
|
||
```java
|
||
if (s1.equals(s2)) { // ПРАВИЛЬНО
|
||
// строки равны
|
||
}
|
||
|
||
if (s1 == s2) { // НЕПРАВИЛЬНО (сравнивает ссылки)
|
||
// это не то, что вы думаете
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 12. Работа с тестами
|
||
|
||
### 12.1. Репозиторий с тестами
|
||
- Тесты выкладываются в отдельный репозиторий
|
||
- Доступны исходный код и скомпилированная версия (.jar файлы)
|
||
|
||
### 12.2. Запуск тестов
|
||
|
||
#### Шаги для запуска
|
||
1. Скачать .jar файл с тестами
|
||
2. Скомпилировать свою программу
|
||
3. Проверить наличие .class файла
|
||
4. Запустить тесты командой
|
||
|
||
#### Пример команды запуска
|
||
```bash
|
||
java -cp <путь_к_тестируемому_классу>:<путь_к_тест.jar> <название_теста>
|
||
```
|
||
|
||
**Рекомендация:** Создать скрипт для автоматизации запуска тестов
|
||
|
||
### 12.3. Требования к решениям
|
||
- Для второго ДЗ: промежуточные результаты должны помещаться в `int`
|
||
- Использовать можно всё из стандартной поставки Java
|
||
- Неправильное использование → минусы при сдаче
|
||
|
||
---
|
||
|
||
## 13. Дополнительное задание: Run.me
|
||
|
||
### 13.1. Описание
|
||
- **Необязательное** задание для тех, кому "нечего делать"
|
||
- Содержит как простые, так и откровенно сложные задачи
|
||
- Предназначено для дополнительной практики
|
||
|
||
### 13.2. Рекомендации
|
||
- ✅ Посмотреть полчасика
|
||
- ✅ Получить доступные плюсики
|
||
- ✅ Перейти к основному ДЗ
|
||
- ⚠️ НЕ закапываться в Run.me - это плохая стратегия!
|
||
|
||
### 13.3. Оценивание
|
||
- Максимум баллов не больше, чем за обычное ДЗ
|
||
- Выполнить обычное ДЗ **гораздо полезнее**
|
||
- Сложность оценивается по количеству решивших
|
||
- Оценка: коэффициент × количество решённых задач
|
||
|
||
### 13.4. Технические детали
|
||
- Можно использовать **всё что угодно**
|
||
- Проверяется только правильность URL результата
|
||
- Код НЕ проверяется (в отличие от обычных ДЗ)
|
||
- Каждая строка = отдельное число (не склеиваются)
|
||
- Не надо показывать код преподавателю
|
||
|
||
---
|
||
|
||
## 14. Система баллов и оценок
|
||
|
||
### 14.1. Начисление очков
|
||
- Очки начисляются за сдачу домашних заданий
|
||
- Видны в специальной таблице (НЕ в БАРСе)
|
||
- Несдача ДЗ = 0 очков
|
||
|
||
### 14.2. Важные замечания
|
||
- ⚠️ Нельзя сравнивать очки за разные ДЗ
|
||
- ⚠️ Нельзя сравнивать очки между группами
|
||
- ✅ Гарантируется **локальная справедливость** внутри группы
|
||
|
||
### 14.3. Локальная справедливость
|
||
**Правило:**
|
||
```
|
||
Если студент A и студент B:
|
||
- Решили одинаковые ДЗ
|
||
- У A не больше задержки, чем у B
|
||
- У A не больше минусов, чем у B
|
||
→ То у A точно не меньше баллов, чем у B
|
||
```
|
||
|
||
### 14.4. Конвертация в БАРС
|
||
- Конвертация происходит **в конце курса**
|
||
- Очки нормируются относительно группы
|
||
- Чем больше очков относительно коллег → выше оценка
|
||
|
||
### 14.5. Критерии оценок
|
||
- **Для 5 (отлично):** > 90 баллов в БАРСе
|
||
- За каждое ДЗ гарантируется минимальный процент баллов
|
||
- Сдать ДЗ **всегда** строго лучше, чем не сдать
|
||
- Разница между "сдано" и "не сдано" **существенная**
|
||
|
||
### 14.6. Причины разброса баллов
|
||
- Результаты Run.me (различия в решённых задачах)
|
||
- Задержки при сдаче
|
||
- Количество минусов
|
||
- Относительный перформанс в группе
|
||
|
||
### 14.7. Интерпретация статуса
|
||
- 🟢 **Зелёный** → всё хорошо
|
||
- 🔴 **Красный** → проблемы, нужно подтянуться
|
||
|
||
---
|
||
|
||
## 15. Практические рекомендации
|
||
|
||
### 15.1. Стратегия успешной сдачи
|
||
1. ✅ Начинать делать ДЗ сразу после выдачи
|
||
2. ✅ Стремиться сдать в первую неделю (delay = 0)
|
||
3. ✅ Тщательно проверять код перед демонстрацией
|
||
4. ✅ Использовать тесты для самопроверки
|
||
5. ✅ Создать скрипты для автоматизации
|
||
|
||
### 15.2. Работа с кодом
|
||
- Можно использовать линтеры для Java
|
||
- Следить за качеством кода
|
||
- Исправлять замечания преподавателя
|
||
- Помнить о накоплении минусов
|
||
|
||
### 15.3. Что НЕ стоит делать
|
||
- ❌ Откладывать ДЗ на последнюю неделю
|
||
- ❌ Закапываться в Run.me вместо основного ДЗ
|
||
- ❌ Игнорировать замечания преподавателя
|
||
- ❌ Сравнивать свои баллы с другими группами
|
||
|
||
---
|
||
|
||
## 16. Обратная связь
|
||
|
||
### 16.1. Если недоволен результатом
|
||
- Использовать кнопку 👎 (thumbs down) под ответами
|
||
- Написать в чат курса
|
||
- Отправить email преподавателю
|
||
|
||
### 16.2. Если что-то непонятно
|
||
- Задавать вопросы в чате
|
||
- Подходить к преподавателю после лекции
|
||
- Писать на email для сложных вопросов
|
||
|
||
---
|
||
|
||
## Резюме первой лекции
|
||
|
||
### Ключевые выводы
|
||
1. **Организация:** Лекции → ДЗ → Практика (сдача модификаций)
|
||
2. **Оценивание:** Очки → конвертация в БАРС → итоговая оценка
|
||
3. **Java:** Популярный, простой, безопасный, кроссплатформенный язык
|
||
4. **Стратегия:** Сдавать быстро, качественно, регулярно
|
||
|
||
### Что делать дальше
|
||
1. Настроить среду разработки (JDK установлен)
|
||
2. Начать второе домашнее задание
|
||
3. Скачать и настроить тесты
|
||
4. Стремиться сдать в первую неделю
|
||
|
||
### Важные даты
|
||
- Сдача ДЗ: каждый вторник (3 попытки)
|
||
- Досрочный зачёт: конец декабря
|
||
- Стандартный зачёт: сессия
|
||
|
||
---
|
||
|
||
## Полезные ссылки
|
||
- Чат курса (основные вопросы)
|
||
- Email преподавателя (сложные вопросы)
|
||
- Репозиторий с тестами
|
||
- Материалы курса
|
||
- Раздел "Ошибки и опечатки" в чате
|
||
|
||
---
|
||
|
||
**Успехов в изучении Java! 🚀**
|