JavaRush /Курсы /C# SELF /Обзор основных типов коллекций

Обзор основных типов коллекций

C# SELF
27 уровень , 0 лекция
Открыта

1. Введение

Давайте честно, массивы — отличная штука, но у них есть ограничения. Нужно поменять размер? Придется создавать новый массив и вручную копировать элементы! Нужно быстро искать элемент по ключу? Массив скажет: "Ну, попробуй сделать это сам".

Реальная жизнь полна сценариев, где массивы неудобны. Представьте себе, что вы пишете приложение для учета книг в библиотеке (привет, наша учебная мини-система!). Сначала у вас 5 книг — вроде бы хватает массива. Через неделю их уже 500, а еще через месяц кто-то вернул книгу, а кто-то потерял... Здесь на помощь приходят коллекции!

Коллекции — это такие контейнеры, которые умеют:

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

В .NET есть несколько ключевых "семейств" коллекций. Сегодня мы познакомимся с основными: списки (List<T>), словари (Dictionary<TKey, TValue>), множества (HashSet<T>), очереди, стеки, а также с интерфейсами, которые лежат в их основе.

2. Основные виды коллекций

Несмотря на то, что мы еще не углублялись в конкретные типы обобщенных коллекций, важно понимать, какие существуют основные категории коллекций и для каких задач они подходят. Думайте об этом как о разных видах "контейнеров", каждый со своими особенностями:

Списки (Lists)

Что это? Упорядоченная последовательность элементов. Как обычный список покупок или список студентов в журнале.

Ключевые особенности: Элементы имеют порядок (можно получить по индексу, как в массиве). Могут содержать повторяющиеся элементы. Размер динамический.

Когда использовать? Когда важен порядок следования элементов, и вы хотите иметь возможность быстро добавлять/удалять элементы в конец списка, или получать элементы по их позиции.

Пример из жизни: Очередь на кассе, список участников вебинара, последовательность кадров в анимации.

Словари/Отображения (Dictionaries/Maps)

Что это? Набор пар "ключ-значение". Похоже на настоящий словарь, где у каждого слова (ключа) есть свое значение (определение).

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

Когда использовать? Когда вам нужно быстро найти значение по какому-то уникальному идентификатору (ключу).

Пример из жизни: Записная книжка (имя - телефон), база данных товаров (ID товара - описание), настройки приложения (имя настройки - значение).

Множества (Sets)

Что это? Неупорядоченный набор уникальных элементов. Как математическое множество.

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

Когда использовать? Когда вам нужно хранить уникальные значения и быстро проверять, присутствует ли элемент в наборе.

Пример из жизни: Список уникальных посетителей сайта, набор тегов для статьи, список слов для автодополнения (без повторов).

Очереди (Queues)

Что это? Коллекция, работающая по принципу "первый пришел — первый вышел" (FIFO - First-In, First-Out).

Ключевые особенности: Элементы добавляются в конец очереди и удаляются из начала.

Когда использовать? Моделирование процессов, где порядок обработки важен, например, система тикетов поддержки, очередь на печать.

Стеки (Stacks)

Что это? Коллекция, работающая по принципу "последний пришел — первый вышел" (LIFO - Last-In, First-Out).

Ключевые особенности: Элементы добавляются и удаляются с одного конца (вершины стека).

Когда использовать? Отслеживание истории действий (отмена действия в редакторе), обработка вложенных структур, рекурсия.

Различия между типами коллекций

Тип коллекции Аналогия Основной принцип Доступ по индексу? Порядок элементов? Дубликаты разрешены? Основные операции
Массив Ряд пронумерованных ячеек Фиксированный размер Да Да Да Получение/установка по индексу
Список Список покупок Динамический, упорядоченный Да Да Да Добавление, удаление, поиск
Словарь Словарь (ключ-значение) Уникальные ключи Нет Нет (обычно) Нет (по ключу) Получение по ключу, добавление
Множество Набор уникальных объектов Только уникальные элементы Нет Нет Нет Проверка наличия, объединение
Очередь Очередь на кассе FIFO (Первый пришел - первый ушел) Нет Да Да Добавление в конец, извлечение из начала
Стек Стопка тарелок LIFO (Последний пришел - первый ушел) Нет Да Да Добавление наверх, извлечение сверху

3. Список: List<T>

Список - это самая часто используемая коллекция в C#. Даже чаще чем массив. Список — коллекция, которая похожа на массив, но умеет расти сама. Можно добавлять и удалять элементы без головной боли.


using System;
using System.Collections.Generic;

var numbers = new List<int>();         // Создаём пустой список целых чисел
numbers.Add(10);                      // Добавляем элемент
numbers.Add(15);
numbers.Add(42);

Console.WriteLine(numbers[0]);        // 10

numbers.Remove(15);                   // Удаляем элемент по значению

foreach (var number in numbers)
{
    Console.WriteLine(number);
}
// Выведет: 10 и 42

Почему List<T> лучше массива для коллекции данных, размер которой заранее неизвестен?
— Потому что не нужно вручную выделять больше памяти и копировать массив при добавлении элементов — всё делает коллекция!

Когда использовать List<T>?

  • Динамический список, когда элементы можно добавлять, удалять, изменять.
  • Не нужен быстрый поиск по ключу (это про словари).
  • Часто используем для работы с упорядоченными наборами.

4. Словарь Dictionary<TKey, TValue>

Массив (и список) позволяет хранить список значений в ячейках массива, и у каждой ячейки есть индекс. А вот словарь - это коллекция, которая позволяем вместо числа (индекса) использовать строку (имя). Такое имя ячейки называется ключом.

Если нужно по какому-то ключу быстро получить значение (например, по номеру читательского билета — имя читателя), то нужен словарь.


using System.Collections.Generic;

var phoneBook = new Dictionary<string, string>();
phoneBook["Аня"] = "+79992221133";
phoneBook["Максим"] = "+79998887766";

Console.WriteLine(phoneBook["Аня"]);      // +79992221133

// Можно проверить, есть ли ключ:
if (phoneBook.ContainsKey("Вася"))
{
    Console.WriteLine(phoneBook["Вася"]);
}
else
{
    Console.WriteLine("Нет такого номера!");
}

Интересный факт: Словари часто называют "ассоциативными массивами". Они реализованы на основе хеш-таблицы, что позволяет выполнять поиск по ключу очень быстро (почти мгновенно, если не считать коллизии — но об этом чуть позже).

Ключевые особенности

  • Ключ уникален: в словаре не может быть двух одинаковых ключей.
  • Значения могут повторяться.
  • Очень быстро ищет, добавляет, удаляет элементы по ключу.

5. Множество: HashSet<T>

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

Например, вам нужно просто знать, есть ли что-то в наборе, без дубликатов, и неважен порядок — тогда используем множество.


using System.Collections.Generic;

var knownUsers = new HashSet<string>();
knownUsers.Add("admin");
knownUsers.Add("guest");
knownUsers.Add("admin");    // Повторное добавление — игнорируется

Console.WriteLine(knownUsers.Contains("admin"));  // True
Console.WriteLine(knownUsers.Count);              // 2

Множество очень быстро проверяет наличие элемента.

Зачем нужны множества?
— Если, например, хотите хранить всех уникальных пользователей, открывших приложение за месяц, или, скажем, список уникальных авторов книг.

Особенности

  • Хранит только уникальные элементы (вставка дубликата игнорируется).
  • Нет индексов, как у списка.
  • Быстрая проверка наличия.

6. Очереди и стеки

Есть еще структуры для специальных случаев: очередь и стек. Фактически это тот же список, только с регулируемым добавлением и извлечением элементов.

Queue<T>: очередь (first in — first out)

Иногда нужно держать "очередь" — новый элемент встаёт в конец, а забирать их нужно с начала.


using System.Collections.Generic;

var queue = new Queue<string>();
queue.Enqueue("Первый");
queue.Enqueue("Второй");
queue.Enqueue("Третий");

Console.WriteLine(queue.Dequeue()); // "Первый"
Console.WriteLine(queue.Peek());    // "Второй", но не удаляет

Stack<T>: стек (first in — last out)

Стек работает наоборот: последний зашёл — первый вышел. Применяется в парсерах, обработке вызовов функций и даже при отмене действий в редакторах.


using System.Collections.Generic;

var stack = new Stack<string>();
stack.Push("Один");
stack.Push("Два");
stack.Push("Три");

Console.WriteLine(stack.Pop());  // "Три"
Console.WriteLine(stack.Peek()); // "Два"

7. Таблица: сравнение основных коллекций

Коллекция Уникальные элементы Доступ по индексу Быстрый поиск по ключу Операции вставки/удаления
List<T>
Нет Да Нет Быстрый в конец
Dictionary<K,V>
Ключи Нет Да Быстрый по ключу
HashSet<T>
Да Нет Да* Быстрый по значению
Queue<T>
Нет Нет Нет Быстрый (FIFO)
Stack<T>
Нет Нет Нет Быстрый (LIFO)

Каждую коллекцию мы подробно разберем в следующих лекциях. А начнем мы с загадочной буквы <T>...

2
Задача
C# SELF, 27 уровень, 0 лекция
Недоступна
Создание и заполнение списка
Создание и заполнение списка
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Александр Уровень 39
29 января 2026
задач и так было мало (про их качество молчу), так теперь будет ещё меньше...