3_Массивы и Коллекции
Урок 3 : Массивы и Коллекции
Когда данных много - одной переменной недостаточно. Массивы и коллекции позволяют хранить наборы значений и эффективно работать с ними.
1. Массивы (Array)
Массив - это как пронумерованные ячейки в шкафчиках раздевалки: количество ячеек фиксировано при создании, и к каждой обращаются по номеру (индексу).
Упорядоченный набор элементов одного типа с фиксированным размером. Размер задаётся при создании и не меняется.
// Объявление и создание массива из 5 элементов
int[] scores = new int[5]; // все элементы = 0 по умолчанию
// Объявление с инициализацией
int[] damage = { 10, 25, 7, 42, 18 };
// Явный синтаксис
string[] names = new string[] { "Артём", "Мария", "Иван" };
// Доступ по индексу (нумерация с 0!)
Console.WriteLine(damage[0]); // 10 - первый элемент
Console.WriteLine(damage[4]); // 18 - последний
damage[2] = 99; // изменить элемент
// Длина массива
Console.WriteLine(damage.Length); // 5
Первый элемент - arr[0], последний - arr[arr.Length - 1]. Обращение к arr[arr.Length] вызовет IndexOutOfRangeException.
Перебор массива
int[] numbers = { 5, 3, 8, 1, 9 };
// Через for - когда нужен индекс
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine($"[{i}] = {numbers[i]}");
}
// Через foreach - когда индекс не нужен
foreach (int num in numbers)
{
Console.Write(num + " ");
}
Полезные методы для массивов
int[] arr = { 5, 3, 8, 1, 9 };
Array.Sort(arr); // сортировка по возрастанию: 1, 3, 5, 8, 9
Array.Reverse(arr); // разворот: 9, 8, 5, 3, 1
int idx = Array.IndexOf(arr, 5); // найти индекс элемента со значением 5 в массиве arr
Array.Fill(arr, 0); // заполнить все элементы массива arr значением 0
Многомерные массивы
// Двумерный массив (матрица 3x3)
int[,] grid = new int[3, 3];
grid[0, 0] = 1;
grid[1, 2] = 5;
// Инициализация
int[,] matrix = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
Console.WriteLine(matrix[1, 1]); // 5 - центр матрицы
// Перебор
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
2. Коллекции. Чем они отличаются от массива?
| Характеристика | Массив Т[] |
Коллекция (напр. List<Т>) |
|---|---|---|
| Размер | Фиксированный | Динамический |
| Добавление элементов | Невозможно без пересоздания | Просто: Add(), Insert() |
| Удаление элементов | Нельзя | Просто: Remove(), RemoveAt() |
| Производительность | Чуть быстрее при прямом доступе | Небольшие накладные расходы |
| Функциональность | Минимальная | Богатый API |
- Знаете размер заранее и он не меняется →
Array - Размер неизвестен или изменяется →
List<Т> - Нужен поиск по ключу →
Dictionary<ТKey, ТValue>
3. List<Т> - динамический список
List<Т> напоминает список покупок: можно добавлять позиции в любом месте, вычёркивать их, и список сам подстраивает свой размер.
Хранит элементы одного типа в порядке добавления. Самая используемая коллекция.
using System.Collections.Generic;
// Создание
List<int> scores = new List<int>();
List<string> players = new List<string> { "Артём", "Мария" };
// Добавление
scores.Add(100); // в конец
scores.Add(200);
scores.Insert(0, 50); // по индексу: 50, 100, 200
// Доступ
Console.WriteLine(scores[0]); // 50
Console.WriteLine(scores.Count); // 3 (не Length, а Count!)
// Поиск
bool has = scores.Contains(100); // true
int idx = scores.IndexOf(200); // 2
// Удаление
scores.Remove(100); // удалить первое вхождение значения
scores.RemoveAt(0); // удалить по индексу
// Сортировка
scores.Sort(); // по возрастанию
scores.Reverse(); // разворот
// Очистка
scores.Clear();
Перебор List
List<string> weapons = new List<string> { "Меч", "Лук", "Посох" };
foreach (string w in weapons)
Console.WriteLine(w);
// С индексом через for
for (int i = 0; i < weapons.Count; i++)
Console.WriteLine($"{i}: {weapons[i]}");
В Unity List<Т> используется повсюду: список врагов, инвентарь предметов, очередь событий. Это стандартный инструмент для любого динамического набора объектов.
4. Dictionary<ТKey, ТValue> - словарь
Dictionary - как записная книжка: открываете по имени контакта и сразу видите его номер телефона. Хранит пары ключ / значение, ключи уникальны, поиск по ключу мгновенный (O(1)).
// Создание
Dictionary<string, int> stats = new Dictionary<string, int>();
Dictionary<int, string> months = new Dictionary<int, string>
{
{ 1, "Январь" },
{ 2, "Февраль" },
{ 3, "Март" }
};
// Добавление
stats["strength"] = 15;
stats["agility"] = 12;
stats.Add("intelligence", 8); // Add бросит исключение, если ключ уже есть
// Доступ
Console.WriteLine(stats["strength"]); // 15
Console.WriteLine(months[2]); // Февраль
// Безопасный доступ (без исключения если ключ отсутствует)
if (stats.TryGetValue("luck", out int luckValue))
Console.WriteLine($"Удача: {luckValue}");
else
Console.WriteLine("Ключ не найден");
// Проверка наличия ключа
bool hasKey = stats.ContainsKey("agility"); // true
bool hasVal = stats.ContainsValue(15); // true
// Изменение
stats["agility"] = 20;
// Удаление
stats.Remove("intelligence");
// Количество
Console.WriteLine(stats.Count);
Перебор Dictionary
// Перебор пар ключ-значение
foreach (KeyValuePair<string, int> pair in stats)
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
// Краткая запись с var
foreach (var pair in stats)
Console.WriteLine($"{pair.Key} = {pair.Value}");
// Только ключи
foreach (string key in stats.Keys)
Console.WriteLine(key);
// Только значения
foreach (int val in stats.Values)
Console.WriteLine(val);
Dictionary не гарантирует порядок перебора. Если нужен упорядоченный словарь - используйте SortedDictionary<ТKey, ТValue>.
Для углублённого изучения
HashSet<Т> - множество уникальных элементов
HashSet<Т> хранит только уникальные значения (дубликаты игнорируются). Очень быстрая проверка наличия элемента (O(1)).
HashSet<string> tags = new HashSet<string>();
tags.Add("fire");
tags.Add("magic");
tags.Add("fire"); // дубликат - игнорируется!
Console.WriteLine(tags.Count); // 2
Console.WriteLine(tags.Contains("fire")); // true - мгновенная проверка
// Операции над множествами
HashSet<int> setA = new HashSet<int> { 1, 2, 3, 4 };
HashSet<int> setB = new HashSet<int> { 3, 4, 5, 6 };
setA.IntersectWith(setB); // Пересечение: { 3, 4 }
setA.UnionWith(setB); // Объединение: { 1, 2, 3, 4, 5, 6 }
setA.ExceptWith(setB); // Разность: { 1, 2 }
- Проверка, встречался ли уже этот элемент (посещённые комнаты, собранные предметы)
- Исключение дубликатов из набора
- Когда List.Contains() работает слишком медленно на больших данных
Сравнение коллекций
| Коллекция | Уникальность | Порядок | Доступ | Когда использовать |
|---|---|---|---|---|
List<T> |
Нет | Да | По индексу | Упорядоченный список |
Dictionary<К,V> |
По ключу | Нет | По ключу | Пары ключ-значение |
HashSet<T> |
Да | Нет | Нет | Уникальные элементы |
Итог урока
- Массив - фиксированный набор элементов одного типа; индексация с 0
List<Т>- динамический список; основная коллекция для повседневных задачDictionary<ТKey, ТValue>- пары ключ/значение; мгновенный поиск по ключуHashSet<Т>- только уникальные значения; быстрая проверка Contains
📋 Перейти к практическим заданиям урока 3