Предисловие
Статья входит в подборку: C# Starter Pack: Учимся с нуля
Удобная навигация по подборке: тык
Введение
Привет, дружище! Сегодня у нас новая тема из нашего крутого C# Starter Pack. Посмотри на прошлую статью, если пропустил: тыкай сюда.
А сегодня мы будем разбирать коллекции, поехали!
Какие коллекции существуют? Давай разбираться!
1. Списки (List)
В списках ты можешь хранить куча вещей, которые тебе захочется, но определенного типа. Примеры: список покупок, плейлист любимых треков или просто рандомные числа для какой-то задачки. Вот тут-то и приходит на помощь List!
Примеры использования:
А выгода то какая? Массивы же есть! Так вот:
Плюсы:
- Гибкость: Ты можешь добавлять и удалять элементы на лету.
- Простота использования: Легко пользоваться, есть много удобных методов для работы со списком (Find, Sort, Exists, Add, Remove и т.д.).
Минусы:
- Память: За удобство приходится платить размером. List занимает больше памяти, чем массивы.
- Производительность: Если список очень большой, добавление и удаление элементов может быть медленным.
2. Словари (Dictionary)
Словарик как каталог с быстрым доступом по ключу. Удобно, когда знаешь, что ищешь.
Примеры использования:
Плюсы:
- Быстрый доступ: Как найти нужную вещь? Просто скажи ключевое слово!
- Уникальность ключей: Все ключи уникальные, как отпечатки пальцев.
- Гибкость: Можешь хранить всё, что угодно.
Минусы:
- Ключи обязательны: Без ключа не засунешь и не вытащишь вещь.
- Память: Жрет памяти больше, чем простой список.
3. Очереди (Queue)
У очередей принцип простой: первый пришел, первый ушел. Идеально для ситуаций, когда порядок важен.
Примеры использования:
Плюсы:
- Честность: Все честно, кто первый пришел, тот первый и ушел.
- Простота: Ничего сложного, все как в жизни — очередь и все дела.
- Удобство: Идеально для задач, где важен порядок элементов.
Минусы:
- Не для всех: Если тебе нужен доступ к случайному элементу, то Queue не подойдет. А по индексу? - увы, не работает.
- Ограниченный функционал: Тут не понатыкаешь много разных фишек, только основное.
- Память: Как и всякий список, жрет памяти больше, чем простые массивы.
4. Стеки (Stack)
Стек - это как куча тарелок в раковине. Последняя пришла, первая ушла.
Примеры использования:
Плюсы:
- Простота: Все просто, как в стопке блинов — верхний блинчик самый доступный.
- Скорость: Доступ к верхнему элементу происходит моментально.
- Идеально для определенных задач: Как например, последовательное отмена действий в приложении.
Минусы:
- Ограниченный доступ: Только верхний элемент доступен, остальные ждут своей очереди.
- Не для всех задач: Если тебе нужен доступ ко всем элементам, то стек — не твой выбор.
- Менеджмент: Нужно следить, чтобы стек не был пустым, когда ты пытаешься что-то из него достать, иначе выплюнет ошибку.
5. HashSet
HashSet - это типо коллекции редких марок, где каждая марка является уникальной. Если ты попытаешься добавить еще одну такую же, то она просто в эту коллекцию не войдет и будет проигнорирована. Данный контейнер хранит только уникальные элементы, автоматически отсеивая дубликаты, поэтому он отлично подходит, когда тебе нужны только уникальные элементы.
Примеры использования:
Плюсы:
- Уникальность: Только уникальные значения, никаких повторений.
- Быстрый доступ: Проверка наличия элемента происходит очень быстро.
- Оптимизация: Экономит время и ресурсы, когда важно избегать дубликатов.
Минусы:
- Ограниченный функционал: Только основные операции, без изысков.
- Уникальность: Если тебе нужны повторения, то тебе не сюда.
6. SortedSet
Теперь это не только уникальные марки, но еще и отсортированные друг за другом!
Примеры использования:
Плюсы:
- Порядок: Все аккуратненько и по полочкам.
- Быстрый поиск: Найти кого-то в этой толпе легче, чем в хаотичной.
- Уникальность: Дубликатов нет, каждый гость — особенный.
Минусы:
- Скорость добавления: Приходится подождать, пока SortedSet всех расставит.
- Больше памяти: За порядок приходится платить.
- Гибкость: Ты не контролируешь порядок, SortedSet решит за тебя.
7. LinkedList
LinkedList - это как гусеница, где каждый сегмент связан с предыдущим и следующим элементом.
Примеры использования:
Плюсы:
- Гибкость: Можешь добавлять и удалять узлы, где угодно.
- Эффективность: Добавление и удаление узлов не требует перестановки всей коллекции.
Минусы:
- Доступ к элементам: Нет доступа по индексу.
- Больше памяти: Каждый узел хранит информацию о своих соседях.
- Скорость доступа: Не такой шустрый, как массив или List, если тебе нужен конкретный элемент.
8. Concurrent Collections
В C# есть специальные коллекции для многопоточных приложений: ConcurrentBag, ConcurrentQueue, ConcurrentStack, и ConcurrentDictionary. Они отлично подходят для ситуаций, когда нужно обеспечить безопасность при параллельном доступе. Представь себе автобан, где машины (потоки) летят на полной скорости и при этом не мешают друг другу. В C# такие коллекции помогают безопасно работать с данными из разных потоков без столкновений и аварий.
❗️Многопоточность и параллельное программирование мы будем проходить в отдельных статьях.
А теперь чуть более подробно:
- ConcurrentQueue: Как обычная очередь, но безопасная для использования несколькими потоками одновременно.
- ConcurrentStack: То же, что и стек, но адаптированный для многопоточности.
- ConcurrentBag: Подходит, когда порядок не важен, а важна скорость и безопасность (альтернатива обычному списку, но для многопоточных задач).
- ConcurrentDictionary: Как обычный словарь, но безопасен для доступа из разных потоков.
А теперь перейдем к плюсам и минусам данных коллекций!
Плюсы:
- Многопоточность: Работай с данными из любого потока без проблем.
- Безопасность: Никаких аварий при одновременном доступе.
- Эффективность: Оптимизированы для высокой производительности.
Минусы:
- Сложность: Немного сложнее в использовании, чем обычные коллекции.
- Ресурсоемкость: Могут использовать больше ресурсов.
- Специфичность: Нужны только в многопоточных сценариях.
9. ObservableCollection
Данная коллекция умеет сообщать о своих изменениях. Каждый раз, когда ты добавляешь, удаляешь или меняешь элемент, ObservableCollection шлёт новости всем, кто подписался.
Когда может пригодится?
Допустим ты хочешь, чтобы твоя приложуха с графическим интерфейсом динамично меняла свой интерфейс в зависимости от данных коллекции (кнопок там, списка клиентов твоего магазина т.д.).
❗️Если ты еще не в курсе про события и с чем их едят - не переживай! Будем проходить и разбирать их в будущих статьях.
Небольшой пример кода:
А вот и реализация самих уведомлялок при изменении коллекции:
А вот что у нас получается на выходе:
Наши бенефиты:
Плюсы:
- Автоматическое уведомление: Все подписчики на коллекцию в курсе изменений. Как только что-то меняется в коллекции, все знают об этом.
- Удобство в интерфейсах: Отлично подходит для динамических интерфейсов пользователя, особенно в MVVM, где важно отображать актуальные данные.
- Гибкость: Подходит для сценариев, где данные часто меняются и эти изменения должны быть отражены в реальном времени.
Минусы:
- Производительность: При большом количестве подписчиков или частых изменениях может замедлить производительность.
- Сложность: Нужно управлять подписками и уведомлениями, что добавляет сложности в код.
10. ReadOnly Collections
Эти коллекции только для чтения. Ты можешь смотреть, но не трогать. Отлично подходят, когда ты хочешь предоставить доступ к данным без риска их изменения.
Какие бывают?
- ReadOnlyCollection: Обертка для обычных коллекций, делающая их только для чтения.
- ReadOnlyList, ReadOnlyDictionary, ReadOnlyObservableCollection, ReadOnlySet (HashSet, SortedSet): Предоставляют доступ к элементам коллекции без возможности изменения.
❗️ ReadOnly мы будем проходить в отдельной статье.
Небольшой пример кода:
А в чем выгода?
Плюсы:
- Безопасность: Данные в безопасности, их нельзя случайно изменить.
- Стабильность: Идеально подходят для передачи данных без риска их модификации.
Минусы:
- Не для изменений: Если тебе нужно менять данные, это не твой выбор.
- Ограниченность: Меньше функциональности по сравнению с обычными коллекциями.
11. Immutable Collections
А вот мы добрались до коллекций, которые не меняются после создания.
Какие типы коллекций бывают? - Да все стандартные коллекции, добавь только перед названием коллекции "Immutable", к примеру перед List -> ImmutableList, держи пример:
Плюсы:
- Безопасность: Идеально для многопоточных приложений, где изменения могут привести к проблемам.
- Стабильность: Они не изменятся, как бы сильно ни дул ветер перемен.
Минусы:
- Не для изменений: Если ты любишь переменчивость, это не твой выбор.
- Дополнительные ресурсы: Создание новых копий при изменениях может быть ресурсоёмким.
Отличия от ReadOnlyCollections:
Так а в чем отличие от ReadOnlyCollections?
Все очень просто:
- "Неизменяемость" против "только для чтения": ImmutableCollections являются полностью неизменяемыми. После их создания нельзя изменить содержимое коллекции. Любые модификации, такие как добавление или удаление элементов, приводят к созданию новой коллекции с изменениями.
ReadOnlyCollections на самом деле являются обёртками над существующими коллекциями. Они предоставляют только чтение базовой коллекции, но не предотвращают изменения самой базовой коллекции. Если базовая коллекция изменится, то эти изменения отразятся и в ReadOnlyCollection. - Безопасность потоков: ImmutableCollections безопасны для использования в многопоточных средах, так как состояние коллекций никогда не изменяется после их создания, а ReadOnlyCollections не гарантируют безопасность потоков, так как базовая коллекция может быть изменена другим потоком.
- Производительность: ImmutableCollections обычно более медленные и потребляют больше памяти по сравнению с ReadOnlyCollections, так как изменения требуют создания новых коллекций. ReadOnlyCollections Могут быть более эффективными по памяти и скорости, так как они просто оборачивают существующие коллекции.
12. Frozen Collections
Замороженные коллекции — это очень надежные хранилища данных, которые нельзя изменить после создания. Они идеально подходят для сценариев, где требуется высокая скорость чтения и стабильность данных, например, в многопоточных приложениях или когда нужно обеспечить неприкосновенность данных.
Данные коллекции появились только в .NET Core 8! Держи статью, если упустил краткий обзор новинки:
Как использовать:
Плюсы и минусы:
Плюсы:
- Оптимизация производительности: Особенно эффективны в сценариях, где требуется быстрое чтение данных.
- Неприкосновенность данных: Отличный выбор для сохранения целостности и стабильности данных.
- Безопасность для многопоточности: Поскольку данные не изменяются, они безопасны для использования в многопоточных приложениях.
Минусы:
- Отсутствие гибкости: Невозможность изменять данные может быть ограничивающим фактором в некоторых сценариях.
- Необходимость заранее определить данные: Данные должны быть полностью определены на этапе создания коллекции.
Отличия от Immutable Collections вот в чем:
- Гибкость: Immutable Collections не позволяют изменять существующие экземпляры, но позволяют создавать новые измененные копии. Это значит, что ты можешь "изменить" коллекцию, добавив или удалив элементы, но на самом деле это приведет к созданию новой коллекции с этими изменениями. В свою очередь, Frozen Collections не предоставляют возможности создать измененную копию. Frozen Collections полностью и абсолютно неизменны после создания.
- Производительность: Создание новых копий Immutable Collections при каждом изменении может быть ресурсоемким, особенно для больших коллекций, в то время как Frozen Collections не могут создавать своих копий и оптимизированы для сценариев, где требуется быстрое и эффективное чтение данных, таких как многопоточные операции или высокопроизводительные приложения.
Практические задания:
List:
- Создай список своих любимых игр и добавь туда 5 названий.
- Удали из списка игру, в которую ты уже наигрался.
- Выведи на экран вторую по счету игру из списка.
Dictionary:
- Создай словарь из твоих контактов в мобильном телефоне.
- Удали контакты, с которыми редко общаешься.
- Выведи на экран все пары из словаря.
Queue:
- Создай очередь из твоих любимых игр и добавь туда 3 игры.
- Убери из очереди первую игру (та, что была добавлена первой).
- Проверь, какая игра теперь первая в очереди.
Stack:
- Создай стек из твоих любимых фильмов и добавь туда 3 фильма.
- Убери из стека последний добавленный фильм (он же первый для удаления).
- Проверь, какой фильм теперь на верхушке стека.
HashSet:
- Создай HashSet из твоих любимых песен.
- Попробуй добавить одну песню дважды и проверь, получится ли у тебя.
- Удали одну песню из HashSet и проверь, действительно ли он исчез.
SortedSet:
- Создай SortedSet из твоих любимых сериалов.
- Добавь еще пару сериалов и посмотри, в каком порядке они встанут.
- Найди и удали сериал, который находится в начале списка.
LinkedList:
- Создай LinkedList из твоего плей-листа.
- Добавь еще одну песню в начало и одну в конец списка.
- Удали одну песню из середины списка.
ReadOnly Collections:
- Cоздай ReadOnlyCollection из членов твоей семьи.
- Попробуй добавить или удалить родственника из ReadOnlyCollection и посмотри, что произойдет.
Immutable Collections:
- Создай ImmutableList из твоих любимых книг.
- Попробуй добавить или удалить книгу из списка и проверь, что получилось.
Заключение
Вот тебе обзор всех коллекций в C#. Если у тебя будут вопросы - стучись, не стесняйся. Тут мы все друзья!
Автор, ты забыл про LINQ! Как ты посмел оскорбить наши чувства? 😡😡😡
А вот про LINQ я не забыл, но LINQ - тема отдельной статьи, поэтому мы обязательно затронем такой прекрасный инструмент в будущем. Статей по этой теме будет явно несколько, ведь есть еще и PLINQ, а там кваказябра поинтереснее будет.
Данная статья является последней из текущей подборки:
Держи ссылку на следующую подборку, где мы будем рассматривать ООП и другие сложные штуки 🌟:
Ставь ❤️ и подписывайся на канал, до новых встреч!
Предыдущая статья: тык
Поддержать автора: