Хочешь уверенно проходить IT-интервью?

Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.
💡 Почему Т1 тренажёр — это мастхэв?
- Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
- Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
- Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.
Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!
Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy
Список List<T>
List<T>
— класс из пространства имен System.Collections.Generic
, список однотипных объектов. В отличие от массива, предоставляет набор методов, облегчающих работу, таких как добавление новых элементов (это удобно, когда неизвестно заранее сколько будет элементов).
Есть несколько вариантов создания списка:
Создание списка без начальных значений
//List<T> list = new List<T>(); //T - выбранный тип, например int
//Пример:
List<int> list = new List<int>();
//Примеры других типов:
List<string> sList = new List<string>();
List<object> oList = new List<object>();
Нет ограничений на тип, который можно поместить в список.
Создание списка с начальными значениями
//List<T> list = new List<T>(){ Item1, Item2, Item3… }; //Item1/2/3 - элементы нашего списка, тип которых T
//List<T> list = new List<T>{ Item1, Item2, Item3… }; // Тоже допустимо
//Пример:
List<int> list = new List<int> { 1, 2, 3 }; //Мы создали список с набором чисел
Создание на основе другого списка
List<int> list = new List<int> { 1, 2, 3 };
List<int> list2 = new List<int>(list);
Надо заметить, что это не то же самое, что и list2 = list
, т. к. при передаче списка в конструктор нового списка создается именно новый список, т. е. в памяти выделяется место для нового объекта, но заполняется теми же значениями, которые были в переданном списке.
Комбинированный подход
List<int> list = new List<int> { 1, 2, 3 };
List<int> list2 = new List<int>(list) { 4 };
Если вывести все значения из списка list2
, будут выведены значения от 1 до 4.
Также рассмотрим более сложный пример с пользовательским классом.
class Cup
{
public string Name { get; set; }
public int Capacity { get; set; }
public ConsoleColor Color { get; set; }
public Cup(string name)
{
Name = name;
}
}
List<Cup> cups = new List<Cup>
{
new Cup("Моя кружка") {
Color = ConsoleColor.White,
Capacity = 1000
},
new Cup("Не моя кружка") {
Color = ConsoleColor.Black,
Capacity = 300
}
};
Установка начальной емкости списка
Помимо перечисленных выше конструкторов, есть еще один, который принимает размер начальной емкости списка:
List<int> list = new List<int>(10);
Внутри списка находится массив, который при заполнении определенной емкости динамически расширяется, чтобы снизить издержки на выделение памяти при добавлении элементов. На низком уровне при проверке расширения проверяется, если в массиве (который внутри списка) нет элементов, то его размер выставляется равным _defaultCapacity
(переменная в исходниках, которая имеет начальное значение = 4), в противном случае считается из «количество элементов» * 2. Т. е. всякий раз, когда мы достигаем определенной границы массива, List
автоматически расширяет его в 2 раза, однако ограничение списка — это 2G (Array.MaxArrayLength – 2146435071) элементов. Для повышения производительности, если известен конечный размер списка, можно изначально задать его размер, что избавит от дополнительных выделений памяти.
Обращение к элементам списка
Аналогично как в массиве, допустимо обращаться к элементам списка в квадратных скобках по индексу.
List<int> list = new List<int>() { 3, 4, 2, 0 };
Console.WriteLine(list[0]);// 3
list[0] = 7;
Console.WriteLine(list[0]);// 7
List<int> list1 = new List<int>();
list1[0] = 1; // Получим исключение ArgumentOutOfRangeException, т.е. для начала нужно создать хоть один элемент списка

Длина списка
Для определения длины списка используется свойство Count
.
List<int> list = new List<int>() { 3, 4, 2, 0 };
Console.WriteLine(list.Count); // 4
list = new List<int>();
Console.WriteLine(list.Count); // 0

Перебор списка
Для перебора списка можно использовать классический цикл, например for
.
List<int> list = new List<int>() { 3, 4, 2, 0 };
for(int i = 0; i < list.Count; i++)
Console.WriteLine(list[i]);

Также существует специальный цикл для работы со списками foreach
.
List<int> list = new List<int>() { 3, 4, 2, 0 };
foreach(int item in list)
Console.WriteLine(item);

Методы списка
Наконец, добрались до самого интересного — методы, которые улучшают работу со списком по сравнении с массивом. Рассмотрим следующие методы (полный список методов можно посмотреть в документации 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<int> list = new List<int>();
for (int i = 0; i < 10; i++)
{
list.Add(i); // Добавление элемента в конец списка
list.AddRange(new[] { i + 4, i + 5 }); // Добавление коллекции элементов в конец списка
list.Insert(i, i + 1); // Вставка элемента по индексу i
list.InsertRange(i, new[] { i + 2, i + 3 }); // Вставка массива/коллекции по индексу i
}
Удаление из списка
List<int> list = new List<int>() { 0, 1, 2, 9, 32, -7 }; // Создали массив с элементами
Console.WriteLine(string.Join(",", list));
if (list.Remove(9)) // Удаляем 9
Console.WriteLine("Элемент 9 успешно удален.");
Console.WriteLine(string.Join(",", list));
list.RemoveAt(0); // Удаляем 0
Console.WriteLine(string.Join(",", list));
list.RemoveAll(i => i < 0); // Удаляем -7
Console.WriteLine(string.Join(",", list));
list.RemoveRange(0, 2); // Удаляес 1 и 2
Console.WriteLine(string.Join(",", list));
list.Clear(); // Удаляем все оставшиеся элементы - 32
Console.WriteLine(string.Join(",", list));

Поиск и проверка элемента
List<int> list = new List<int> { 0, 0, 1, -7, 9, 2, 32, 16, 42 };
//Индексы
//Поиск первого четного индекса
Console.WriteLine(list.FindIndex(i => i % 2 == 0)); // 0
//Поиск последнего четного индекса
Console.WriteLine(list.FindLastIndex(i => i % 2 == 0)); // 8
//Поиск индекса по числу из списка
Console.WriteLine(list.IndexOf(-7)); // 3
//Попробуем найти индекс числа которого нет в списке
Console.WriteLine(list.IndexOf(13)); // -1
//Поиск последнего индекса по числу из списка
Console.WriteLine(list.LastIndexOf(0)); // 1
list.Sort(); // Отсортируем массив, так как это основное условие бинарного поиска
Console.WriteLine(list.BinarySearch(9)); // 5
//Проверка вхождения
//Проверим есть ли в списке четные числа
Console.WriteLine(list.Exists(i => i % 2 == 0)); // true
Console.WriteLine(list.Contains(0)); // true
Console.WriteLine(list.Contains(13)); // false
//Значения
//А теперь получим первое четное число
Console.WriteLine(list.Find(i => i % 2 == 0)); // 0
//Найдем все четные числа
Console.WriteLine(string.Join(",", list.FindAll(i => i % 2 == 0))); // 0,0,2,16,32,42
//Последнее четное число
Console.WriteLine(string.Join(",", list.FindLast(i => i % 2 == 0))); // 42
//Получим подсписок, первые 4 элемента
Console.WriteLine(string.Join(",", list.GetRange(0, 4))); // -7,0,0,1
Получение диапазона и копирование в массив
List<int> list = new List<int> { 0, 0, 1, -7, 9, 2, 32, 16, 42 };
var range = list.GetRange(2, 3); // Получим диапазон/подсписок
int[] part = new int[range.Count]; // Объявим массив куда будем копировать диапазон
range.CopyTo(part); // Скопируем диапазон
Console.WriteLine(string.Join(",", part)); // 1,-7,9

Расположение элементов в обратном порядке
List<int> list = new List<int> { 0, 0, 1, -7, 9, 2, 32, 16, 42 };
list.Reverse();
Console.WriteLine(string.Join(",", list)); // 42,16,32,2,9,-7,1,0,0
list.Reverse(1, 3);
Console.WriteLine(string.Join(",", list)); // 42,2,32,16,9,-7,1,0,0

В статье рассмотрена работа с коллекцией List
, рассмотрена базовая работа (инициализация, обращение к данными) и методы для работы со списком:
- Добавление.
- Поиск.
- Удаление.
- Сортировка.
- Работа с диапазонами.
Комментарии