Курс лекций для студентов специальности i-31 03 04 Информатика всех форм обучения Минск 2010


ТИПЫ ДЛЯ РАБОТЫ С КОЛЛЕКЦИЯМИ-МНОЖЕСТВАМИ



страница9/29
Дата09.08.2019
Размер0.64 Mb.
#126834
ТипКурс лекций
1   ...   5   6   7   8   9   10   11   12   ...   29

2.11. ТИПЫ ДЛЯ РАБОТЫ С КОЛЛЕКЦИЯМИ-МНОЖЕСТВАМИ


В библиотеке базовых классов платформы .NET имеются два класса для представления множеств (то есть коллекций, которые не содержат повторяющихся элементов)  HashSet и SortedSet. Оба класса реализуют интерфейс ISet.

Класс HashSet описывает множество, в котором вхождение элемента проверяется на основе хэш-кода. Конструкторы класса HashSet позволяют создать множество на основе коллекции, а также указать объект, реализующий интерфейс IEqualityComparer для проверки равенства элементов множества. Кроме реализации интерфейса ISet, класс HashSet содержит экземплярный метод RemoveWhere() для удаления элементов, удовлетворяющих заданному предикату. Статический метод CreateSetComparer() возвращает экземпляр класса, реализующего IEqualityComparer>. Следующий пример показывает использование HashSet:

var setOne = new HashSet("the quick brown fox");

var setTwo = new HashSet("jumps over the lazy dog");

setOne.IntersectWith(setTwo); // the uro

Console.WriteLine(setOne.Contains('t')); // True

Console.WriteLine(setOne.Contains('j')); // False

setTwo.RemoveWhere(c => c < 'k');

Класс SortedSet  это множество, поддерживающее набор элементов в отсортированном порядке. Конструкторы класса SortedSet позволяют создать множество на основе коллекции, а также указать объект, реализующий интерфейс IComparer для проверки порядка элементов множества. Набор методов SortedSet схож с набором методов класса HashSet. Экземплярный метод Reverse() изменяет порядок элементов на противоположный, а метод GetViewBetween() возвращает фрагмент («окно») исходного множества между двумя элементами.

var setOne = new SortedSet("А роза упала на лапу Азора");

// setOne = Аазлнопру

var setTwo = setOne.GetViewBetween('б', 'р');

setTwo.Add('в'); // успешно, setTwo = взлнопр

setTwo.Add('ф'); // исключение, так как символ не принадлежит окну


2.12. ТИПЫ ДЛЯ РАБОТЫ С КОЛЛЕКЦИЯМИ-СЛОВАРЯМИ


Под термином словарь будем понимать коллекцию, которая хранит пары «ключ-значение» с возможностью доступа к элементам по ключу. Базовая библиотека платформы .NET предлагает набор коллекций-словарей, как классических, так и с различными дополнительными возможностями.

Универсальный класс Dictionary – это классический словарь с возможностью указать тип для ключа и тип для значения1. Данный класс является одним из наиболее часто используемых классов-коллекций (наряду с классом List). Класс Dictionary реализует обе версии интерфейса IDictionary (как обычную, так и универсальную). Пример использования класса приведён ниже.

// конструируем словарь и помещаем в него один элемент

var d = new Dictionary {{"One", 1}};

d["Two"] = 2; // помещаем ещё один элемент, используя индексатор

d["Two"] = 22; // обновляем существующий элемент

d["Three"] = 3;

Console.WriteLine(d["Two"]); // печатает "22"

Console.WriteLine(d.ContainsKey("One")); // True (быстрая операция)

Console.WriteLine(d.ContainsValue(3)); // True (медленная операция)

int val;

if (!d.TryGetValue("onE", out val))

Console.WriteLine("No val");
// Различные способы перечисления словаря

foreach (var kv in d)

{

Console.WriteLine(kv.Key + "; " + kv.Value);



}

foreach (string s in d.Keys) { Console.WriteLine(s); }

foreach (int i in d.Values) { Console.WriteLine(i); }

Словарь может работать с элементами любого типа, так как у любого объекта можно получить хэш-код и сравнить объекты на равенство, используя методы GetHashCode() и Equals(). Пользовательские типы могут переопределять данные методы, предоставляя их эффективную реализацию. Кроме этого, конструктору словаря можно передать объект, реализующий интерфейс IEqualityComparer. Типичным примером использования такого подхода является конструирование словаря, обеспечивающего сравнение строк-ключей независимо от их регистра:

var d = new Dictionary(StringComparer.OrdinalIgnoreCase);

Класс OrderedDictionary – это слаботипизированный класс, запоминающий порядок добавления элементов в словарь. В некотором смысле, данный класс является комбинацией классов Hashtable и ArrayList. Для доступа к элементам в OrderedDictionary можно использовать как ключ, так и целочисленный индекс.

Класс ListDictionary использует для хранения элементов словаря не хэш-таблицу, а односвязный список. Это делает данный класс неэффективным при работе с большими наборами данных. ListDictionary рекомендуется использовать, если количество хранимых элементов не превышает десяти. Класс HybridDictionary – это форма словаря, использующая список для хранения при малом количестве элементов, и переключающаяся на применение хэш-функции, когда количество элементов превышает определённый порог. Оба класса ListDictionary и HybridDictionary являются слаботипизированными и находятся в пространстве имен System.Collections.Specialized.

Платформа .NET предоставляет три класса-словаря, организованных так, что их элементы всегда отсортированы по ключу:



    • SortedDictionary;

    • SortedList;

    • SortedList (универсальная версия SortedList).

Данные классы используют разные внутренние структуры для хранения элементов словаря. Класс SortedDictionary быстрее классов SortedList и SortedList при выполнении вставки элементов. Но классы SortedList и SortedList могут предоставить возможность, которой нет у SortedDictionary  доступ к элементу не только по ключу, а и с использованием целочисленного индекса.

2.13. ТИПЫ ДЛЯ СОЗДАНИЯ ПОЛЬЗОВАТЕЛЬСКИХ КОЛЛЕКЦИЙ


Типы коллекций, описанные в предыдущих параграфах, применимы в большинстве стандартных ситуаций. Однако иногда требуется создать собственный тип-коллекцию. Например, в случае, когда изменение коллекции должно генерировать событие, или когда необходима дополнительная проверка данных при помещении их в коллекцию. Для облегчения решения этой задачи платформа .NET предлагает несколько классов, размещённых в пространстве имён System.Collections.ObjectModel.

Универсальный класс Collection является настраиваемой оболочкой над классом List1. В дополнение к реализации интерфейсов IList и IList, класс Collection определяет четыре виртуальные метода ClearItems(), InsertItem(), RemoveItem(), SetItem() и свойство для чтения Items, имеющее тип IList. Переопределяя виртуальные методы, можно модифицировать нормальное поведение класса List при изменении набора.

Рассмотрим пример использования Collection. Пусть класс Track представляет отдельную композицию музыкального альбома. Класс Album наследуется от Collection и описывает альбом. Виртуальные методы класса Collection переопределяются, чтобы корректно изменять значение свойства Album у объекта Track.

public class Track

{

public string Title { get; set; }



public uint Length { get; set; }

public Album Album { get; internal set; }

}
public class Album : Collection

{

protected override void InsertItem(int index, Track item)



{

base.InsertItem(index, item);

item.Album = this;

}
protected override void SetItem(int index, Track item)

{

base.SetItem(index, item);



item.Album = this;

}
protected override void RemoveItem(int index)

{

this[index].Album = null;



base.RemoveItem(index);

}
protected override void ClearItems()

{

foreach (Track track in this)



{

track.Album = null;

}

base.ClearItems();



}

}

У класса Collection имеется конструктор, принимающий в качестве параметра объект, реализующий IList. В отличие от других классов коллекций, этот набор не копируется – запоминается ссылка на него. То есть, изменение набора будет означать изменение коллекции Collection (хотя и без вызова виртуальных методов).



Класс ReadOnlyCollection  это наследник Collection, предоставляющий доступ для чтения элементов, но не для модификации коллекции. Конструктор класса принимает в качестве параметра объект, реализующий IList. Класс не содержит открытых методов добавления или удаления элемента, но можно получить доступ к элементу по индексу и изменить его.

var album = new Album

{

new Track {Title = "Speak To Me", Length = 68},



new Track {Title = "Breathe", Length = 168},

new Track {Title = "On The Run", Length = 230}

};

var albumReadOnly = new ReadOnlyCollection(album);



albumReadOnly[1].Title = string.Empty;

Класс ObservableCollection  это коллекция, позволяющая отслеживать модификации своего набора данных. Этот класс наследуется от Collection и реализует интерфейс INotifyCollectionChanged, который описывает событие, генерируемое при изменении данных:

public interface INotifyCollectionChanged

{

event NotifyCollectionChangedEventHandler CollectionChanged;



}

Аргумент события CollectionChanged позволяет узнать, какое действие выполнено над набором данных (добавление, удаление, замена элемента), а также получить информацию о новых или удаленных элементах коллекции.

// коллекция album – такая же, как в предыдущем примере

var albumObservable = new ObservableCollection(album);

albumObservable.CollectionChanged +=

delegate(object sender, NotifyCollectionChangedEventArgs e)

{

Console.WriteLine("Action: {0}", e.Action);



foreach (Track item in e.NewItems)

Console.WriteLine("Title: {0}", item.Title);

};

albumObservable.Add(new Track { Title = "Time", Length = 424 });



Абстрактный класс KeyedCollection является наследником Collection. Этот класс добавляет возможность обращения к элементу по ключу (как в словарях). При использовании KeyedCollection требуется переопределить метод GetKeyForItem() для вычисления ключа элемента.

Для демонстрации применения KeyedCollection модифицируем пример с классами Track и Album:

public class Track

{

private string _title;


public string Title

{

get { return _title; }



set

{

if (Album != null && _title != value)



{

Album.ChangeTitle(this, value); // изменение ключа

}

_title = value;



}

}
public uint Length { get; set; }

public AlbumDictionary Album { get; internal set; }

}
public class AlbumDictionary : KeyedCollection

{

protected override string GetKeyForItem(Track item)



{

return item.Title; // ключом будет название композиции

}
internal void ChangeTitle(Track track, string title)

{

ChangeItemKey(track, title); // метод меняет ключ элемента



}
// методы ClearItems(), InsertItem(), RemoveItem(), SetItem()

// реализованы также, как в классе Album

}
// пример использования

var album = new AlbumDictionary

{

new Track {Title = "Speak To Me", Length = 68},



new Track {Title = "Breathe", Length = 168},

new Track {Title = "On The Run", Length = 230}

};

album[0].Length = 0; // обращение по индексу



album["Speak To Me"].Length = 68; // обращение по ключу


Каталог: images
images -> В списке студентов (или магистрантов)
images -> Н. И. Сулейманов Комплект контрольно-оценочных средств для оценки результатов освоения профессионального модуля разработан на основе Федерального государственного образовательного стандарта среднего профессионального
images -> По направлению подготовки
images -> Добавить гаджеты. Добавление гаджетов
images -> Техническое задание № apnip/C. 2/CS/Ind/01 Международный консультант по улучшенной производительности орошаемого земледелия
images -> Комплект контрольно-оценочных средств по профессиональному модулю пм. 01 Техническое обслуживание и ремонт автотранспорта


Поделитесь с Вашими друзьями:
1   ...   5   6   7   8   9   10   11   12   ...   29




База данных защищена авторским правом ©vossta.ru 2022
обратиться к администрации

    Главная страница