Share This
Связаться со мной
Крути в низ
Categories
//Список List

Список List

В статье рассмотрим принципы работы со списком List: создание списка и обращение к данными; добавление, удаление, поиск и сортировка элементов.

spisok list 374d52f - Список List

Список 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, т.е. для начала нужно создать хоть один элемент списка      

spisok list 5298671 - Список List

Доступ к элементам списка

Длина списка

Для определения длины списка используется свойство 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      

spisok list ae8537b - Список List

Получение длины списка

Перебор списка

Для перебора списка можно использовать классический цикл, например for.

         List<int> list = new List<int>() { 3, 4, 2, 0 }; for(int i = 0; i < list.Count; i++) 		Console.WriteLine(list[i]);      

spisok list 54428af - Список List

Перебор списка for

Также существует специальный цикл для работы со списками foreach.

         List<int> list = new List<int>() { 3, 4, 2, 0 }; foreach(int item in list) 		Console.WriteLine(item);      

spisok list fbfd81b - Список List

Перебор списка 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<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));      

spisok list cf46a25 - Список 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      

spisok list a7f727c - Список List

Работа с диапазоном

Расположение элементов в обратном порядке

         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      

spisok list c6800d6 - Список List

Построение элементов в обратном порядке ***

В статье рассмотрена работа с коллекцией List, рассмотрена базовая работа (инициализация, обращение к данными) и методы для работы со списком:

  1. Добавление.
  2. Поиск.
  3. Удаление.
  4. Сортировка.
  5. Работа с диапазонами.

Материалы по теме

  • 👨‍🎓️ Самоучитель по C#: абстрактные классы и члены классов
  • 👨‍🎓️ Учебник по C#: работа с коллекциями Dictionary
  • 🧊 Руководство по С# для начинающих: массивы и цикл foreach

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close