Список List<T>
List<T>
— класс из пространства имен System.Collections.Generic
, список однотипных объектов. В отличие от массива, предоставляет набор методов, облегчающих работу, таких как добавление новых элементов (это удобно, когда неизвестно заранее сколько будет элементов).
Есть несколько вариантов создания списка:
Создание списка без начальных значений
Нет ограничений на тип, который можно поместить в список.
Создание списка с начальными значениями
Создание на основе другого списка
Надо заметить, что это не то же самое, что и list2 = list
, т. к. при передаче списка в конструктор нового списка создается именно новый список, т. е. в памяти выделяется место для нового объекта, но заполняется теми же значениями, которые были в переданном списке.
Комбинированный подход
Если вывести все значения из списка list2
, будут выведены значения от 1 до 4.
Также рассмотрим более сложный пример с пользовательским классом.
Установка начальной емкости списка
Помимо перечисленных выше конструкторов, есть еще один, который принимает размер начальной емкости списка:
Внутри списка находится массив, который при заполнении определенной емкости динамически расширяется, чтобы снизить издержки на выделение памяти при добавлении элементов. На низком уровне при проверке расширения проверяется, если в массиве (который внутри списка) нет элементов, то его размер выставляется равным _defaultCapacity
(переменная в исходниках, которая имеет начальное значение = 4), в противном случае считается из «количество элементов» * 2. Т. е. всякий раз, когда мы достигаем определенной границы массива, List
автоматически расширяет его в 2 раза, однако ограничение списка — это 2G (Array.MaxArrayLength – 2146435071) элементов. Для повышения производительности, если известен конечный размер списка, можно изначально задать его размер, что избавит от дополнительных выделений памяти.
Обращение к элементам списка
Аналогично как в массиве, допустимо обращаться к элементам списка в квадратных скобках по индексу.
Длина списка
Для определения длины списка используется свойство Count
.
Перебор списка
Для перебора списка можно использовать классический цикл, например for
.
Также существует специальный цикл для работы со списками foreach
.
Методы списка
Наконец, добрались до самого интересного — методы, которые улучшают работу со списком по сравнении с массивом. Рассмотрим следующие методы (полный список методов можно посмотреть в документации Microsoft):
Добавление в список
void Add(T item)
— добавляет новый элемент с типомT
в конец списка.void AddRange(IEnumerable<T> collection)
— добавляет в список коллекцию или массив в конец списка.void Insert(int index, T item)
— вставляет элемент в коллекцию по указанному индексу. При выходе за границы коллекции(0 > index или Count-1 < index)
будет сформировано исключениеSystem.ArgumentOutOfRangeException
.void InsertRange(int index, IEnumerable<T> collection)
— аналогично методу выше, только вставляет список элементов по указанному индексу. Также при выходе за границы будет сформировано исключениеSystem.ArgumentOutOfRangeException
.
Поиск и проверка элемента
int BinarySearch(T item)
— бинарный поиск элемента в списке, возвращает индекс элемента. Работает корректно, если список отсортирован. Имеет еще два варианта реализации с дополнительными параметрами для корректного сравнения элементов или указания начальной точки поиска.bool Contains(T item)
— проверка наличия элемента в списке.bool Exists(Predicate<T> match)
— проверяет наличие в списке хотя бы одного элемента удовлетворяющего условиям делегатаmatch
.T Find(Predicate<T> match)
— возвращает первый элемент, удовлетворяющий условиям делегатаmatch
.List<T> FindAll(Predicate<T> match)
— аналогиченFind
, только возвращает все элементы.int FindIndex(Predicate<T> match)
— возвращает первый индекс элемента, удовлетворяющего условиям делегатаmatch
. Имеет еще два варианта реализации с указанием позиции поиска и количества элементов.int FindLastIndex(Predicate<T> match)
— аналогичноFindIndex
, только возвращает индекс последнего элемента, удовлетворяющего условиям делегатаmatch
. Также имеет еще два варианта реализации с указанием позиции поиска и количества элементов.List<T> GetRange(int index, int count)
— этот метод получает подсписок из списка от указанного индекса с указанным количеством элементов.int IndexOf(T item)
— возвращает первый индекс элемента, если он найден в списке либо-1
. Также имеет еще два реализации с указанием позиции поиска и количества элементов.int LastIndexOf(T item)
— возвращает последний индекс элемента, если он найден в списке либо-1
. Также имеет еще два реализации с указанием позиции поиска и количества элементов.
Удаление из списка
bool Remove(T item)
— удаляет первое вхождение указанного элемента из списка. Возвращаетtrue
, если элемент был удален илиfalse
, если нет.int RemoveAll(Predicate<T> match)
— удаляет все элементы, удовлетворяющие условиям делегатаmatch
. Возвращает количество удаленных элементов.void RemoveAt(int index)
— удаляет элемент списка с указанным индексом. При выходе индекса за границы списка формирует исключениеSystem.ArgumentOutOfRangeException
.void RemoveRange(int index, int count)
— удаляет элементы массива с указанного индекса в указанном количестве. Еслиindex
меньше 0 или значение параметра count меньше 0, то будет сформировано исключениеSystem.ArgumentOutOfRangeException
. Если параметрыindex
иcount
не указывают допустимый диапазон элементов в списке, будет сформировано исключениеSystem.ArgumentException
.void Clear()
— удаляет все элементы из списка.
Сортировка списка
void Sort()
— сортирует элементы. В основе лежит алгоритм быстрой сортировки с ограничением глубины рекурсии до 32, при достижении которого используется сортировка кучей.void Reverse()
— изменяет порядок элементов во всем списке на обратный. Имеет перегруженную версию, в которой указывается начальный индекс и количество элементов.
Прочее
List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
— позволяет сконвертировать все типы элементов текущего списка в другой тип. На входе принимает делегат на метод, преобразующий объект от одного типа к другому.void CopyTo(T[] array)
— копирует список в массив. Имеет еще 2 варианта реализации с указанием границ и позиций копирования.void ForEach(Action<T> action)
— это аналог циклаforeach
, только в качестве итерации будет выполняться метод, который на входе принимает элемент с типомT
. Еще одно отличие такого цикла отforeach
состоит в том, что в методе не сработает ниbreak
, ниcontinue
. Аналогомcontinue
при таком подходе можно считатьreturn
.T[] ToArray()
— возвращает массив элементов списка.
Примеры
Добавление в список
В этом примере мы создадим массив и разными способами заполним его в цикле.
Удаление из списка
Поиск и проверка элемента
Получение диапазона и копирование в массив
Расположение элементов в обратном порядке
В статье рассмотрена работа с коллекцией List
, рассмотрена базовая работа (инициализация, обращение к данными) и методы для работы со списком:
- Добавление.
- Поиск.
- Удаление.
- Сортировка.
- Работа с диапазонами.
Комментарии