Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базовые технологии платформы .NET.docx
Скачиваний:
13
Добавлен:
03.11.2018
Размер:
614.46 Кб
Скачать

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()

Усечение размера внутреннего массива до необходимой минимальной величины