- •А.А. Волосевич
- •2. Базовые технологии платформы .Net 5
- •2. Базовые технологии платформы .Net 4
- •2. Базовые технологии платформы .Net
- •2.1. Работа с Числами
- •2.2. Дата и время
- •2.3. Работа со строками и текстом
- •2.4. Преобразование информации
- •2.5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •2.6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •2.7. Перечислители и итераторы
- •2.8. Интерфейсы стандартных коллекций
- •2.9. Массивы и класс system.Array
- •2.10. Типы для работы с коллекциями-списками
- •2.11. Типы для работы с коллекциями-множествами
- •2.12. Типы для работы с коллекциями-словарями
- •2.13. Типы для создания пользовательских коллекций
- •2.14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •2.15. Работа с объектами файЛовой системы
- •2.16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •2.17. Основы xml
- •2.18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имен xml
- •2.19. ДОполнительные возможности обработки xml
- •2.20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •2.21. Состав и взаимодействие сборок
- •2.22. Метаданные и получение информации о типах
- •2.23. Позднее связывание и кодогенерация
- •2.24. Динамические типы
- •2.25. Атрибуты
- •2.26. Файлы конфигуРации
- •2.27. Основы мНогопоточноГо программирования
- •2.28. Синхронизация потоков
- •2.29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •2.30. Асинхронный вызов методов
- •2.31. Процессы и домены
- •2.32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •2.33. Диагностика
2.10. Типы для работы с коллекциями-списками
Рассмотрим типы из базовой библиотеки платформы .NET, применяемые при работе с коллекциями со списковой семантикой.
Класс List<T> из пространства имён System.Collections.Generic ‑ это основной класс для представления наборов, которые допускают динамическое добавление элементов1. Для хранения данных набора используется внутренний массив. Класс List<T> реализует интерфейсы IList<T> и IList. В табл. 8 представлено описание public-элементов класса List<T>.
Таблица 8
Элементы класса List<T>
Элемент |
Описание |
Добавление и удаление элементов |
|
Add() |
Добавление одного элемента |
AddRange() |
Добавление набора элементов |
Insert() |
Вставка элемента в заданную позицию |
InsertRange() |
Вставка набора элементов |
Remove() |
Удаление элемента |
RemoveAt() |
Удаление элемента на указанной позиции со сдвигом остальных |
RemoveRange() |
Удаление диапазона элементов |
RemoveAll() |
Удаление всех элементов, удовлетворяющих заданному предикату |
Индексирование элементов |
|
this[int index] |
Основной индексатор |
GetRange() |
Получение подсписка |
GetEnumerator() |
Получение перечислителя |
Поиск и сортировка |
|
BinarySearch() |
Поиск элемента в упорядоченном наборе |
IndexOf() |
Индекс первого вхождения своего аргумента в набор |
LastIndexOf() |
Индекс последнего вхождения своего аргумента в набор |
Contains() |
Проверка, содержится ли указанный элемент в наборе |
Exists() |
Проверка, содержит ли набор элемент, удовлетворяющий заданному предикату |
Find() |
Возвращает первый элемент, удовлетворяющий предикату, который задан как параметр метода |
FindLast() |
Возвращает первый элемент с конца набора, удовлетворяющий предикату, который задан как параметр метода |
FindAll() |
Возвращает все элементы набора, удовлетворяющие предикату |
FindIndex() |
Возвращает индекс первого вхождения элемента, удовлетворяющего предикату, который задан как параметр метода |
FindLastIndex() |
Возвращает индекс последнего вхождения элемента, удовлетворяющего предикату, который задан как параметр метода |
TrueForAll() |
Возвращает true, если заданный предикат верен для всех элементов набора |
Sort() |
Сортировка набора (возможно, с применением собственного объекта для сравнения элементов) |
Экспорт и конвертирование элементов |
|
ToArray() |
Преобразование набора в массив |
CopyTo() |
Копирование набора или его части в массив |
AsReadOnly() |
Преобразование набора в коллекцию только для чтения |
ConvertAll() |
Конвертирование набора одно типа в набора другого типа |
Другие методы и свойства |
|
Count |
Количество элементов в наборе |
Capacity |
Ёмкость набора |
TrimExcess() |
Усечение размера внутреннего массива до необходимой минимальной величины |
Clear() |
Очистка списка ‑ удаление всех элементов |
Reverse() |
Изменение порядка элементов на противоположный |
ForEach() |
Выполняет указанное действие для всех элементов списка |
Класс List<T> имеет три конструктора. Первый из них ‑ это обычный конструктор без параметров. Второй конструктор позволяет создать набор на основе коллекции – производится копирование элементов коллекции в список. Третий конструктор принимает в качестве параметра начальную ёмкость набора. Ёмкость набора – это количество элементов набора, которое он способен содержать без увеличения размера внутреннего массива.
Следующий код демонстрирует использование некоторых свойств и методов класса List<T>. Обратите внимание, что для добавления элементов в созданный набор применяется возможность инициализации классов-коллекций.
List<string> words = new List<string> { "melon", "avocado" };
words.AddRange(new[] { "banana", "plum" });
words.Insert(0, "lemon");
words.InsertRange(0, new[] { "peach", "nashi" });
words.Remove("melon");
words.RemoveAt(3);
words.RemoveAll(s => s.StartsWith("n"));
List<string> subset = words.GetRange(1, 2);
string[] wordsArray = words.ToArray();
List<string> bigWords = words.ConvertAll(s => s.ToUpper());
List<int> lengths = words.ConvertAll<int>(s => s.Length);
На примере List<T> рассмотрим одну особенность, присущую всем коллекциям. Если в коллекции хранятся структуры, то части структуры нельзя изменить при помощи индексатора коллекции:
public struct Student
{
public string Name { get; set; }
}
var list = new List<Student> {new Student {Name = "Ivanov"}};
list[0].Name = "Petrov"; // ошибка компиляции
Класс LinkedList<T> служит для представления двусвязного списка. Такой список позволяет осуществлять вставку и удаление элемента без сдвига остальных элементов. Однако доступ к элементу по индексу требует прохода по списку. LinkedList<T> реализует интерфейсы ICollection и ICollection<T>. Каждый элемент двусвязного списка представлен объектом LinkedListNode<T>.
public sealed class LinkedListNode<T>
{
public LinkedList<T> List { get; }
public LinkedListNode<T> Next { get; }
public LinkedListNode<T> Previous { get; }
public T Value { get; set; }
}
При добавлении элемента можно указать, чтобы он помещался в начало списка, или в конец списка, или относительно существующего в списке элемента. Для этого класс LinkedList<T> содержит специальные методы:
public void AddFirst(LinkedListNode<T> node);
public LinkedListNode<T> AddFirst(T value);
public void AddLast(LinkedListNode<T> node);
public LinkedListNode<T> AddLast(T value);
public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode);
public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value);
public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode);
public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value);
Аналогичные методы существуют и для удаления элементов списка:
public void RemoveFirst();
public void RemoveLast();
public bool Remove(T value);
public void Remove(LinkedListNode<T> node);
Класс LinkedList<T> содержит свойства для числа элементов, для указания на первый и последний элемент. Имеются методы для поиска элементов.
Ниже приведён пример использования LinkedList<T>.
var tune = new LinkedList<string>();
tune.AddFirst("do"); // do
tune.AddLast("so"); // do - so
tune.AddAfter(tune.First, "re"); // do - re- so
tune.AddAfter(tune.First.Next, "mi"); // do - re - mi- so
tune.AddBefore(tune.Last, "fa"); // do - re - mi - fa- so
tune.RemoveFirst(); // re - mi - fa - so
tune.RemoveLast(); // re - mi - fa
var miNode = tune.Find("mi");
tune.Remove(miNode); // re - fa
tune.AddFirst(miNode); // mi - re - fa
Классы Queue<T> и Stack<T> реализуют структуры данных «очередь» и «стек» на основе массива1. Конструкторы данных классов, как и конструкторы класса List<T>, позволяют создать объект на основе другой коллекции, а также указать значение для ёмкости (но ёмкость не доступна в виде отдельного свойства). Элементы классов вполне предсказуемы и описаны в табл. 9 и табл. 10.
Таблица 9
Элементы класса Queue<T>
Элемент |
Описание |
Clear() |
Очистка очереди ‑ удаление всех элементов |
Contains() |
Проверка, содержится ли указанный элемент в очереди |
CopyTo() |
Копирование очереди в массив |
Count |
Количество элементов (свойство только для чтения) |
Dequeue() |
Извлечение элемента из очереди |
Enqueue() |
Помещение элемента в очередь |
GetEnumerator() |
Получение перечислителя |
Peek() |
Чтение очередного элемента без его удаления из очереди |
ToArray() |
Преобразование очереди в массив |
TrimExcess() |
Усечение размера внутреннего массива до необходимой минимальной величины |
Таблица 10
Элементы класса Stack<T>
Элемент |
Описание |
Clear() |
Очистка стека ‑ удаление всех элементов |
Contains() |
Проверка, содержится ли указанный элемент в стеке |
CopyTo() |
Копирование стека в массив |
Count |
Количество элементов (свойство только для чтения) |
GetEnumerator() |
Получение перечислителя |
Peek() |
Чтение очередного элемента без его удаления из стека |
Pop() |
Извлечение элемента из стека |
Push() |
Помещение элемента в стек |
ToArray() |
Преобразование стека в массив |
TrimExcess() |
Усечение размера внутреннего массива до необходимой минимальной величины |