Класс SortedList
Класс SortedList предназначен для создания коллекции, которая хранит пары ключ/значение в упорядоченном виде, а именно отсортированы по ключу.
Класс SortedList реализует интерфейсы:
•ICollection,
•IEnumerable,
•ICloneable.
Конструктор: public SortedList( )
Наиболее употребимые методы класса SortedList
Метод |
Описание |
|
|
public virtual bool |
Возвращает значение true, если в |
ContainsKey (object key) |
вызывающей SortedList-коллекции со- |
|
держится ключ, заданный параметром |
|
key. В противном случае возвратит |
|
значение false |
|
|
public virtual |
Возвращает значение true, если в |
bool ContainsValue( |
вызывающей SortedList-коллекции со- |
object value) |
держится значение, заданное пара- |
|
метром value. Иначе – false. |
public virtual object |
Возвращает значение, индекс ко- |
GetBylndex(int idx) |
торого задан параметром idx |
public virtual |
Возвращает нумератор типа IDic- |
IDictionaryEnumerator |
tionaryEnumerator |
для |
вызывающей |
GetEnumerator () |
SortedList-коллекции |
|
public virtual object |
Возвращает ключ, индекс которого |
GetKey (int idx) |
задан параметром idx |
|
public virtual IList |
Возвращает IListколлекцию клю- |
GetKeyList() |
чей, хранимых в вызывающей |
|
SortedList-коллекции |
|
public virtual IList |
Возвращает IList-коллекцию зна- |
GetValueList() |
чений, хранимых в вызывающей |
|
SortedList-коллекции |
|
public virtual int |
Возвращает индекс ключа, задан- |
IndexOfKey (object key) |
ного параметром |
key. |
Возвращает |
|
значение -1, если в списке нет задан- |
|
ного ключа |
|
|
public virtual int |
Возвращает индекс первого вхож- |
IndexOfValue ( |
дения значения, заданного парамет- |
object value) |
ром value. Возвращает -1, если в спи- |
|
ске нет заданного ключа |
|
|
|
public virtual void |
Устанавливает значение по индек- |
SetBylndex(int idx, |
су, заданному параметром idx, равным |
object value) |
значению, переданному в параметре |
|
value |
|
|
public static SortedList |
Возвращает синхронизированную |
Synchronized( |
версию SortedList-коллекции, пере- |
SortedList sl) |
данной в параметре sl |
|
|
|
public virtual |
Устанавливает |
свойство capacity |
void TrimToSize() |
равным значению |
свойства Count |
|
|
|
В классе определены индексатор this[ключ] {get; set;}
Объекты коллекции нумеруются, начиная с 0.
Получить предназначенную только для чтения коллекцию ключей или значений, хранимых в SortedList-коллекции, можно с помощью таких свойств:
public virtual ICollection Keys { get; } public virtual ICollection Values { get; }
Порядок следования ключей и значений в полученных коллекциях отражает порядок SortedList-коллекции.
Подобно Hashtable-коллекции, SortedList-список хранит пары ключ/значение в форме структуры типа DictionaryEntry, но с помощью методов и свойств, определенных в классе SortedList, программисты обычно получают отдельный доступ к ключам и значениям.
// Демонстрация SortedList-коллекции. using System ;
using System.Collections ;
class SLDemo
{
public static void Main()
{
//Создаем упорядоченную коллекцию типа SortedList. SortedList sl = new SortedList();
//Добавляем в список элементы.
sl.Add ("здание", |
"жилое помещение"); |
sl.Add ("книга", |
"набор печатных слов"); |
sl.Add ("яблоко", |
"съедобный фрукт"); |
sl.Add ("автомобиль", |
"транспортное средство"); |
//Добавляем элементы с помощью индексатора. sl ["трактор"] = "сельскохозяйственная машина";
//Извлекаем элемент по ключу.
string value = (string) sl ["автомобиль"]; Console.WriteLine ("---по ключу: " + value); Console.WriteLine ("---по индексу: " + sl.GetByIndex(3));
//Получаем коллекцию ключей. ICollection с = sl.Keys;
//Используем ключи для получения значений. Console.WriteLine("\n--Содержимое списка, полученное "
+"с помощью индексатора.");
foreach (string str in с) Console.WriteLine(str + ": " + sl[str]);
sl.Remove("трактор"); // Удалить элемент
// Отображаем список, используя целочисленные индексы. Console.WriteLine("\n--Содержимое списка, полученное "
+ "с помощью целочисленных индексов."); for (int i = 0; i < sl.Count; i++)
Console.WriteLine(sl.GetByIndex(i));
// Отображаем целочисленные индексы элементов списка. Console.WriteLine("\n --Целочисленные индексы" +
" элементов списка."); foreach (string str in с)
Console.WriteLine(str + ": " + sl.IndexOfKey(str));
}
}
Результаты выполнения этой программы таковы (отсортировано):
---по ключу: транспортное средство
---по индексу: сельскохозяйственная машина
--Содержимое списка, полученное с помощью индексатора. автомобиль: транспортное средство здание: жилое помещение книга: набор печатных слов
трактор: сельскохозяйственная машина яблоко: съедобный фрукт
--Содержимое списка, полученное с помощью целочисленных индексов.
транспортное средство жилое помещение набор печатных слов съедобный фрукт
--Целочисленные индексы элементов списка. автомобиль: 0 здание: 1 книга: 2 яблоко: 3
243
Класс Stack
Стек представляет собой список, добавление и удаление элементов к которому осуществляется по принципу "последним пришел — первым об-
служен" (last-in, first-out — LIFO).
Стек — это динамическая коллекция, которая при необходимости увеличивается, чтобы принять для хранения новые элементы.
Стек реализует интерфейсы:
•ICollection,
•IEnumerable,
•ICloneable.
Методы, определенные в классе Stack
Метод |
Описание |
|
public virtual bool |
Возвращает |
значение true, если |
Contains(object value) |
объект value содержится в вызываю- |
|
щем стеке. В противном случае воз- |
|
вращает значение false |
public virtual void Clear() |
Устанавливает свойство Count рав- |
|
ным нулю, тем самым эффективно |
|
очищая стек |
|
public virtual object Peek() |
Возвращает элемент, располо- |
|
женный в вершине стека, но не удаля- |
|
ет его |
|
public virtual object Pop() |
Возвращает элемент, располо- |
|
женный в вершине стека, и удаляет |
|
его |
|
public virtual void |
Помещает объект value в стек |
Push(object value) |
|
|
public static Stack |
Возвращает |
синхронизированную |
Synchronized(Stack stk) |
версию stack-списка, переданного в |
|
параметре stk |
|
public virtual object[ ] |
Возвращает массив, который со- |
|
держит копии элементов вызывающего |
ToArray() |
стека |
|
|
|
|
// Демонстрация использования класса Stack.
using System;
using System. Collections;
class StackDemo
{
public static void Main()
{
int a;
Stack st = new Stack();
st.Push(22);
st.Push(65);
st.Push(91);
foreach (int i in st) Console.Write(i + " ");
Console.WriteLine(); try
{
a = (int)st.Pop(); |
Console.WriteLine(a); |
a = (int)st.Pop(); |
Console.WriteLine(a); |
a = (int)st.Pop(); |
Console.WriteLine(a); |
a = (int)st.Pop(); |
Console.WriteLine(a); |
}
catch (InvalidOperationException)
{
Console.WriteLine("Стек пуст.");
}
}
}
Хранение битов с помощью класса BitArray
Класс BitArray предназначен для поддержки коллекции битов. Поскольку его назначение состоит в хранении битов, а не объектов, то и его возможности отличаются от возможностей других коллекций. Тем не менее, класс BitArray поддерживает базовый набор средств коллекции посредством реализации интерфейсов iCollection, lEnumerable и ICloneable.
С помощью этого конструктора можно создать BitArrayколлекцию заданного размера:
public BitArray (int size)
Здесь параметр size задает количество битов в коллекции, причем все они инициализируются значением false.
public BitArray (bool[] bits)
В этом случае каждый элемент массива bits становится битом BitArray-коллекции. При этом каждый бит в коллекции соответствует элементу массива bits. Более того, порядок элементов массива bits аналогичен порядку битов в коллекции.
BitArray-коллекцию можно также создать из массива байтов. Для этого используйте следующий конструктор:
public BitArray (byte[] bits)
Здесь битами коллекции становится набор битов, содержащийся в массиве bits, причем элемент bits[0] определяет первые восемь битов, элемент bits[1] — вторые восемь битов и т.д.
Подобным образом можно создать Bit Array-коллекцию из массива других типов.
BitArray-коллекций могут быть индексированными. Каждый индекс соответствует определенному биту, причем нулевой индекс соответствует младшему биту.
В коллекции созданы методы для выполнения логических операций с битами.
// Демонстрация использования класса BitArray. using System;
using System.Collections;
class BADemo
{
public static void showBits(string rem, BitArray bits)
{
Console.WriteLine(rem); |
|
for (int i = 0; i < bits.Count; i++) |
|
Console.Write("{0, -6} ", bits[i]); |
|
Console.WriteLine("\n"); |
|
} |
|
public static void Main() |
|
{ |
|
BitArray ba = new BitArray(8); |
// все биты = false |
byte[] b = { 67 }; |
|
BitArray ba2 = new BitArray(b); |
|
Console.Write("Бит 5 = {0, -6} ", ba2[5]); |
|
showBits("Исходное содержимое бит.коллекции ba:", ba);
ba = ba.Not();
showBits ("Содержимое коллек. ba после вызова Not():", ba); showBits("Содержимое коллекции ba2:", ba2);
BitArray ba3 = ba.Xor(ba2);
showBits("Результат операции ba XOR ba2:", ba3);
}
}
2.Специализированные коллекции
Всреде .NET Framework предусмотрена возможность создания специализированных коллекций, которые оптимизированы для работы с конкретными типами данных или для особого вида обработки.
Эти классы коллекций (они определены в пространстве имен System.Collections.Specialized):
Специализиро- |
Описание |
ванная коллекция |
|
CollectionsUtil |
Коллекция, в которой игнорируется раз- |
|
личия между строчным и прописным написа- |
|
нием символов в строках |
HybridDictionary |
Коллекция, в которой для хранения не- |
|
большого числа пар ключ/значение ис- |
|
пользуется класс ListDictionary. Но при пре- |
|
вышении коллекцией определеного размера |
|
для хранения: элементов автоматически ис- |
|
пользуется класс Hashtable |
|
ListDictionary |
Коллекция, в которой для хранения пар |
|
ключ/значение используется связный список. |
|
Такую коллекцию рекомендуется использо- |
|
вать лишь при небольшом количестве эле- |
|
ментов |
|
|
NameValueCollection |
Отсортированная |
коллекция |
пар |
|
ключ/значение, в которой как ключ, так и |
|
значение имеют тип string |
|
|
StringCollection |
Коллекция, оптимизированная для хране- |
|
ния строк |
|
|
StringDictionary |
Хеш-таблица, предназначенная для хра- |
|
нения пар ключ/значение, в которой как |
|
ключ, так и значение имеют тип string |
|
В пространстве имен System.Collections также определены три абст-
рактных базовых класса, CollectionBase, ReadOnlyCollectionBase и DictionaryBase, которые предполагают создание производных классов и предназначены для использования в качестве отправной точки при разработке программистом собственных специализированных классов.
3. Способы сортировки объектов коллекции Реализация интерфейса IComparable
Если необходимо отсортировать динамический массив (типа ArrayList) объектов, определенных пользователем (или, если вам понадобится сохранить эти объекты в коллекции типа SortedList), то вы должны сообщить коллекции информацию о том, как сравнивать эти объекты.
Один из способов — реализовать интерфейс IComparable.
В этом интерфейсе определен только один метод CompareTo(), который позволяет определить, как должно выполняться сравнение объектов соответствующего типа. Общий формат использования метода
CompareTo() таков:
int CompareTo (object obj)
Метод CompareTo() сравнивает вызывающий объект с объектом, заданным параметром obj. Чтобы отсортировать объекты коллекции в возрастающем порядке, этот метод (в вашей реализации) должен возвращать нуль, если сравниваемые объекты равны положительное значение, если вызывающий объект больше объекта obj, и отрицательное число, если вызывающий объект меньше объекта obj.
Для сортировки в убывающем порядке достаточно инвертировать результат описанного сравнения. Метод CompareTo() может сгенерировать
исключение типа ArgumentException, если тип объекта obj несовместим с вызывающим объектом.
//Реализация интерфейса IComparable. using System;
using System.Collections;
class Inventory : IComparable
{
string name; double cost; int onhand;
public Inventory(string n, double c, int h)
{
name = n; cost = c; onhand = h;
}
public override string ToString()
{
return String.Format("{0, -16}Цена: {1,8:C} В наличии: {2}", name, cost, onhand);
}
// Реализуем интерфейс IComparable. public int CompareTo(object obj)
{
Inventory b;
b = (Inventory)obj;
return this.name.CompareTo(b.name);
}
}
class IcomparableDemo
{
public static void Main()
{
ArrayList inv = new ArrayList();
inv.Add(new Inventory("Плоскогубцы", 5.95, 3)); inv.Add(new Inventory("Гаечные ключи", 8.29, 2)); inv.Add(new Inventory("Молотки", 3.50, 4));
Console.WriteLine("---Информация до сортировки:"); foreach (Inventory i in inv)
Console.WriteLine(" " + i);
// Сортируем список. inv.Sort();
Console.WriteLine("---Информация после сортировки:"); foreach (Inventory i in inv)
Console.WriteLine(" " + i);
}
}
Здесь метод сортировки предоставил исходный класс Inventory.
А как быть, если класс не реализует интерфейс IComparable? В этом случае можно воспользоваться интерфейсом IComparer.
Использование интерфейса IComparer
Интерфейс IComparer определяет метод сортировки, у которого ссылка на объект, реализующий метод сравнения, используется в качестве параметра. В интерфейсе IComparer определен только один метод Compare():
int Compare (object obj1, object obj2)
Метод Compare() сравнивает объект obj1 с объектом obj2. Возвращаемое значение то же.
// Использование интерфейса Icomparer.
using System;
using System.Collections;
class CompInv : IComparer
{
public int Compare (object obj1, object obj2)
{
return ((Inventory)obj1).name.CompareTo(((Inventory)obj2).name);
}
} |
|
class Inventory |
|
{ |
|
public string |
name; |
double cost; |
int |
onhand; |
public Inventory(string n, double c, int h)
{
name = n; cost = c; onhand = h;
}
public override string ToString()
{
return String.Format(" {0,-16}Цена: {1,8:C} В наличии: {2}", name, cost, onhand);
}
}
class MailList
{
public static void Main()
{
ArrayList inv = new ArrayList();
// Добавляем элементы в список.
inv.Add(new Inventory("Плоскогубцы", 5.95, 3)); inv.Add(new Inventory("Гаечные ключи", 8.29, 2)); inv.Add(new Inventory("Молотки", 3.50, 4));
Console.WriteLine("Информация до сортировки:"); foreach (Inventory i in inv)
Console.WriteLine(" " + i); Console.WriteLine();
// Сортируем список, используя интерфейс IComparer. inv.Sort(new CompInv());
Console.WriteLine("Информация после сортировки:"); foreach (Inventory i in inv)
Console.WriteLine(" " + i);
}
}
4. Сериализация коллекций
Все классы коллекций общего назначения и специализированные коллекции имеют атрибут [Serializable]. Следовательно, такие коллекции можно сохранять на диске с помощью одного обращения к методу Serialize(). Затем так же одним вызовом метода Deserialize() можно восстановить коллекцию в памяти.
Таблица коллекций и часто используемых методов
|
Добавить |
Извлечь с |
Прочитать |
Удалить |
Коллекция |
элемент |
удалением |
элемент |
элемент |
ArrayList |
al.Add(ob) |
|
ob=al [i] |
al.Remove(key) |
Queue |
q.Enqueu(ob) |
q.Dequeu() |
ob=q.Peek() |
|
Hashtable |
ht.Add(ob) |
|
ob=ht [key] |
ht.Remove(key) |
|
ht [key]=ob |
|
|
|
SortedList |
sl.Add(ob) |
|
ob=sl [key] |
sl.Remove(key) |
|
sl [key]=ob |
|
sl.GetByIndex(i) |
|
Stack |
st.Push(ob) |
st.Pop() |
ob=st.Peek() |
|