355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Герберт Шилдт » C# 4.0: полное руководство » Текст книги (страница 76)
C# 4.0: полное руководство
  • Текст добавлен: 6 апреля 2017, 04:00

Текст книги "C# 4.0: полное руководство"


Автор книги: Герберт Шилдт



сообщить о нарушении

Текущая страница: 76 (всего у книги 83 страниц)

// Продемонстрировать применение класса SortedList.

using System;

using System.Collections;

class SLDemo {

  static void Main() {

    // Создать отсортированный список.

    SortedList si = new SortedList();

    // Добавить элементы в список.

    si.Add(«здание», «жилое помещение»);

    si.Add(«автомашина», «транспортное средство»);

    si.Add(«книга», «набор печатных слов»);

    si.Add(«яблоко», «съедобный плод»);

    // Добавить элементы с помощью индексатора,

    si["трактор"] = «сельскохозяйственная машина»;

    // Получить коллекцию ключей.

    ICollection с = si.Keys;

    // Использовать ключи для получения значений.

    Console.WriteLine(«Содержимое списка по индексатору.»);

    foreach(string str in с)

      Console.WriteLine(str + ": " + si[str]);

    Console.WriteLine();

    // Отобразить список, используя целочисленные индексы.

    Console.WriteLine(«Содержимое списка по целочисленным индексам.»);

    for(int i=0; i < si.Count; i++)

      Console.WriteLine(si.GetByIndex(i)) ;

    Console.WriteLine() ;

    // Показать целочисленные индексы элементов списка.

    Console.WriteLine(«Целочисленные индексы элементов списка.»);

    foreach(string str in с)

      Console.WriteLine(str + ": " + si.IndexOfKey(str));

  }

}

Ниже приведен результат выполнения этой программы.

Содержимое списка по индексатору.

автомашина: транспортное средство

здание: жилое помещение

книга: набор печатных слов

трактор: сельскохозяйственная машина

яблоко: съедобный плод

Содержимое списка по целочисленным индексам.

транспортное средство

жилое помещение

набор печатных слов

сельскохозяйственная машина

съедобный плод

Целочисленные индексы элементов списка.

автомашина: 0

здание: 1

книга: 2

трактор: 3

яблоко: 4


Класс Stack

Как должно быть известно большинству читателей, стек представляет собой список, действующий по принципу «первым пришел – последним обслужен». Этот принцип действия стека можно наглядно представить на примере горки тарелок, стоящих на столе. Первая тарелка, поставленная в эту горку, извлекается из нее последней. Стек относится к одним из самых важных структур данных в вычислительной технике. Он нередко применяется, среди прочего, в системном программном обеспечении, компиляторах, а также в программах отслеживания в обратном порядке на основе искусственного интеллекта

Класс коллекции, поддерживающий стек, носит название Stack. В нем реализуются интерфейсы ICollection, IEnumerable и ICloneable. Этот класс создает динамическую коллекцию, которая расширяется по мере потребности хранить в ней вводимые элементы. Всякий раз, когда требуется расширить такую коллекцию, ее емкость увеличивается вдвое.

В классе Stack определяются следующие конструкторы.

public Stack()

public Stack(int initialCapacity)

public Stack(ICollection col)

В первой форме конструктора создается пустой стек, во второй форме – пустой стек, первоначальный размер которого определяет первоначальная емкость, задаваемая параметром initialCapacity, ив третьей форме – стек, содержащий элементы указываемой коллекции col. Его первоначальная емкость равна количеству указанных элементов.

В классе Stack определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Некоторые из наиболее часто используемых методов этого класса приведены в табл. 25.7. Эти методы обычно применяются следующим образом. Для того чтобы поместить объект на вершине стека, вызывается метод Push(). А для того чтобы извлечь и удалить объект из вершины стека, вызывается метод Pop(). Если же объект требуется только извлечь, но не удалить из вершины стека, то вызывается метод Реек(). А если вызвать метод Pop() или Реек(), когда вызывающий стек пуст, то сгенерируется исключение InvalidOperationException.

Таблица 25.7. Наиболее часто используемые методы, определенные в классе Stack

Метод – Описание

public virtual void Clear() – Устанавливает свойство Count равным нулю, очищая, по существу, стек

public virtual bool Contains (objectobj) – Возвращает логическое значение true, если объект obj содержится в вызывающем стеке, а иначе – логическое значение false

public virtual object Peek() –  Возвращает элемент, находящийся на вершине стека, но не удаляет его

public virtual object Pop() – Возвращает элемент, находящийся на вершине стека, удаляя его по ходу дела

public virtual void Push (objectobj) – Помещает объект obj в стек

public static Stack Synchronized(Stackstack) – Возвращает синхронизированный вариант коллекции типа Stack, передаваемой в качестве параметра stack

public virtual object[] ToArray() – Возвращает массив, содержащий копии элементов вызывающего стека

В приведенном ниже примере программы создается стек, в который помещается несколько целых значений, а затем они извлекаются обратно из стека.

// Продемонстрировать применение класса Stack.

using System;

using System.Collections;

class StackDemo {

  static void ShowPush(Stack st, int a) {

    st.Push(a);

    Console.WriteLine("Поместить в стек: Push(" + a + ")");

    Console.Write("Содержимое стека: ");

    foreach(int i in st)

      Console.Write(i + " ");

    Console.WriteLine();

  }

  static void ShowPop(Stack st) {

    Console.Write("Извлечь из стека: Pop -> ");

    int a = (int) st.Pop();

    Console.WriteLine(а);

    Console.Write("Содержимое стека: ");

    foreach(int i in st)

      Console.Write(i + " ");

    Console.WriteLine();

  }

  static void Main() {

    Stack st = new Stack();

    foreach(int i in st)

      Console.Write(i + " ");

    Console.WriteLine();

    ShowPush(st, 22);

    ShowPush(st, 65);

    ShowPush(st, 91);

    ShowPop(st);

    ShowPop(st);

    ShowPop(st) ;

    try {

      ShowPop(st) ;

    } catch (InvalidOperationException) {

      Console.WriteLine(«Стек пуст.»);

    }

  }

}

Ниже приведен результат выполнения этой программы. Обратите внимание на то, как обрабатывается исключение InvalidOperationException, генерируемое при попытке извлечь элемент из пустого стека.


Поместить в стек: Push(22)

Содержимое стека: 22

Поместить в стек: Push(65)

Содержимое стека: 65 22

Поместить в стек: Push(91)

Содержимое стека: 91 65 22

Извлечь из стека: Pop -> 91

Содержимое стека: 65 22

Извлечь из стека: Pop -> 65

Содержимое стека: 22

Извлечь из стека: Pop -> 22

Содержимое стека:

Извлечь из стека: Pop -> Стек пуст.


Класс Queue

Еще одной распространейной структурой данных является очередь, действующая по принципу: первым пришел – первым обслужен. Это означает, что первым из очереди извлекается элемент, помещенный в нее первым. Очереди часто встречаются в реальной жизни. Многим из нас нередко приходилось стоять в очередях к кассе в банке, магазине или столовой. В программировании очереди применяются для хранения таких элементов, как процессы, выполняющиеся в данный момент в системе, списки приостановленных транзакций в базе данных или пакеты данных, полученные по Интернету. Кроме того, очереди нередко применяются в области имитационного моделирования.

Класс коллекции, поддерживающий очередь, носит название Queue. В нем реализуются интерфейсы ICollection, IEnumerable и ICloneable. Этот класс создает динамическую коллекцию, которая расширяется, если в ней необходимо хранить вводимые элементы. Так, если в очереди требуется свободное место, ее размер увеличивается на коэффициент роста, который по умолчанию равен 2,0.

В классе Queue определяются приведенные ниже конструкторы.

public Queue()

public Queue (int capacity)

public Queue (int capacity, float growFactor)

public Queue (ICollection col)

В первой форме конструктора создается пустая очередь с выбираемыми по умолчанию емкостью и коэффициентом роста 2,0. Во второй форме создается пустая очередь, первоначальный размер которой определяет емкость, задаваемая параметром capacity, а коэффициент роста по умолчанию выбирается для нее равным 2,0. В третьей форме допускается указывать не только емкость (в качестве параметра capacity), но и коэффициент роста создаваемой очереди (в качестве параметра growFactor в пределах от 1,0 до 10,0). И в четвертой форме создается очередь, состоящая из элементов указываемой коллекции col. Ее первоначальная емкость равна количеству указанных элементов, а коэффициент роста по умолчанию выбирается для нее равным 2,0.

В классе Queue определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Некоторые из наиболее часто используемых методов этого класса перечислены в табл. 25.8. Эти методы обычно применяются следующим образом. Для того чтобы поместить объект в очередь, вызывается метод Enqueue(). Если требуется извлечь и удалить первый объект из начала очереди, то вызывается метод Dequeue(). Если же требуется извлечь, но не удалять следующий объект из очереди, то вызывается метод Реек(). А если методы Dequeue() и Реек() вызываются, когда очередь пуста, то генерируется исключение InvalidOperationException.

Таблица 25.8. Наиболее часто используемые методы, определенные в классе Queue

Метод – Описание

public virtual void Clear() – Устанавливает свойство Count равным нулю, очищая, по существу, очередь

public virtual bool Contains(object obj) – Возвращает логическое значение true, если объект obj содержится в вызывающей очереди, а иначе – логическое значение false

public virtual object Dequeue() – Возвращает объект из начала вызывающей очереди. Возвращаемый объект удаляется из очереди

public virtual void Enqueue(object obj) – Добавляет объект obj в конец очереди

public virtual object Peek() – Возвращает объект из начала вызывающей очереди, но не удаляет его

public static Queue Synchronized(Queuequeue) – Возвращает синхронизированный вариант коллекции типа Queue, передаваемой в качестве параметра queue

public virtual object[] ToArray() – Возвращает массив, который содержит копии элементов из вызывающей очереди

public virtual void TrimToSize() –  Устанавливает значение свойства Capacity равным значению свойства Count

В приведенном ниже примере программы демонстрируется применение класса

Queue.

// Продемонстрировать применение класса Queue.

using System;

using System.Collections;

class QueueDemo {

  static void ShowEnq(Queue q, int a) {

    q.Enqueue(a) ;

    Console.WriteLine("Поместить в очередь: Enqueue(" + a + ")");

    Console.Write("Содержимое очереди: ");

    foreach(int i in q)

      Console.Write(i + " ");

    Console.WriteLine() ;

  }

  static void ShowDeq(Queue q) {

    Console.Write("Извлечь из очереди: Dequeue -> ");

    int a = (int) q.Dequeue();

    Console.WriteLine(a);

    Console.Write("Содержимое очереди: ");

    foreach(int i in q)

      Console.Write(i + " ") ;

    Console.WriteLine();

  }

  static void Main() {

    Queue q = new Queue();

    foreach(int i in q)

      Console.Write(i + " ");

    ShowEnq(q, 22);

    ShowEnq(q, 65);

    ShowEnq(q, 91);

    ShowDeq(q);

    ShowDeq(q);

    ShowDeq(q);

    try {

      ShowDeq (q);

    } catch (InvalidOperationException) {

      Console.WriteLine(«Очередь пуста.»);

    }

  }

}

Эта программа дает следующий результат.

Поместить в очередь: Enqueue(22)

Содержимое очереди: 22

Поместить в очередь: Enqueue(65)

Содержимое очереди: 22 65

Поместить в очередь: Enqueue(91)

Содержимое очереди: 22 65 91

Извлечь из очереди: Dequeue -> 22

Содержимое очереди: 65 91

Извлечь из очереди: Dequeue -> 65

Содержимое очереди: 91

Извлечь из очереди: Dequeue -> 91

Содержимое очереди:

Извлечь из очереди: Dequeue -> Очередь пуста.


Хранение отдельных битов в классе коллекции BitArray

Класс BitArray служит для хранения отдельных битов в коллекции. А поскольку в коллекции этого класса хранятся биты, а не объекты, то своими возможностями он отличается от классов других коллекций. Тем не менее в классе BitArray реализуются интерфейсы ICollection и IEnumerable как основополагающие элементы поддержки всех типов коллекций. Кроме того, в классе BitArray реализуется интерфейс ICloneable.

В классе BitArray определено несколько конструкторов. Так, с помощью приведенного ниже конструктора можно сконструировать объект типа BitArray из массива логических значений.

public BitArray(bool[] values )

В данном случае каждый элемент массива values становится отдельным битом в коллекции. Это означает, что каждому элементу массива values соответствует отдельный бит в коллекции. Более того, порядок расположения элементов в массиве values сохраняется и в коллекции соответствующих им битов.

Коллекцию типа BitArray можно также составить из массива байтов, используя следующий конструктор.

public BitArray( byte[] bytes)

Здесь битами в коллекции становится уже целый их набор из массива bytes, причем элемент bytes [0] обозначает первые 8 битов, элемент bytes[1] – вторые 8 битов и т.д. Аналогично, коллекцию типа BitArray можно составить из массива целочисленных значений, используя приведенный ниже конструктор.

public BitArray(int[ ] values)

В данном случае элемент values[0] обозначает первые 32 бита, элемент values[1] – вторые 32 бита и т.д.

С помощью следующего конструктора можно составить коллекцию типа BitArray, указав ее конкретный размер:

public BitArray(int length)

где length обозначает количество битов в коллекции, которые инициализируются логическим значением false. В приведенном ниже конструкторе можно указать не только размер коллекции, но и первоначальное значение составляющих ее битов.

public BitArray(int length, bool defaultValue)

В данном случае все биты в коллекции инициализируются значением defaultValue, передаваемым конструктору в качестве параметра.

И наконец, новую коллекцию типа BitArray можно создать из уже существующей, используя следующий конструктор.

public BitArray(BitArray bits)

Вновь сконструированный объект будет содержать такое же количество битов, как и в указываемой коллекции bits, а в остальном это будут две совершенно разные коллекции.

Коллекции типа BitArray подлежат индексированию. По каждому индексу указывается отдельный бит в коллекции, причем нулевой индекс обозначает младший бит.

В классе BitArray определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Методы этого класса приведены в табл. 25.9. Обратите внимание на то, что в классе BitArray не поддерживается метод Synchronized(). Это означает, что для коллекций данного класса синхронизированная оболочка недоступна, а свойство IsSynchronized всегда имеет логическое значение false. Тем не менее для управления доступом к коллекции типа BitArray ее можно синхронизировать для объекта, предоставляемого упоминавшимся ранее свойством SyncRoot.

Таблица 25.9. Методы, определенные в классе BitArray

Метод – Описание

public BitArray And(BitArray value) – Выполняет операцию логического умножения И битов вызывающего объекта и коллекции value. Возвращает коллекцию типа BitArray, содержащую результат

public bool Get(intindex) – Возвращает значение бита, указываемого по индексу index

public  BitArray Not() – Выполняет операцию поразрядного логического отрицания НЕ битов вызывающей коллекции и возвращает коллекцию типа BitArray, содержащую результат

public BitArray Or(BitArrayvalue) – Выполняет операцию логического сложения ИЛИ битов вызывающего объекта и коллекции value. Возвращает коллекцию типа BitArray, содержащую результат

public void Set (intindex,boolvalue) – Устанавливает бит, указываемый по индексу index, равным значению value

public void SetAll(boolvalue) – Устанавливает все биты равными значению value

public BitArray Xor(BitArrayvalue) – Выполняет логическую операцию исключающее ИЛИ над битами вызывающего объекта и коллекции value. Возвращает коллекцию типа BitArray, со-

В классе BitArray определяется также собственное свойство, помимо тех, что указаны в интерфейсах, которые в нем реализуются.

public int Length { get; set; }

Свойство Length позволяет установить или получить количество битов в коллекции. Следовательно, оно возвращает такое же значение, как и стандартное свойство Count, определяемое для всех коллекций. В отличие от свойства Count, свойство Length доступно не только для чтения, но и для записи, а значит, с его помощью можно изменить размер коллекции типа BitArray. Так, при сокращении коллекции типа BitArray лишние биты усекаются, начиная со старшего разряда. А при расширении коллекции типа BitArray дополнительные биты, имеющие логическое значение false, вводятся в коллекцию, начиная с того же старшего разряда.

Кроме того, в классе BitArray определяется следующий индексатор.

public bool this[int index] { get; set; }

С помощью этого индексатора можно получать или устанавливать значение элемента. В приведенном ниже примере демонстрируется применение класса 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»);

  }

  static void Main() {

    BitArray ba = new BitArray(8);

    byte[] b = { 67 };

    BitArray ba2 = new BitArray(b);

    ShowBits(«Исходное содержимое коллекции bа:», ba);

    ba = ba.Not();

    ShowBits(«Содержимое коллекции bа после логической операции NOT:», ba);

    ShowBits(«Содержимое коллекции bа2:», ba2);

    BitArray baЗ = ba.Xor(ba2);

    ShowBits(«Результат логической операции ba XOR bа2:», baЗ);

  }

}

Эта программа дает следующий результат.

Исходное содержимое коллекции bа:

False  False  False  False  False  False  False  False

Содержимое коллекции bа после логической операции NOT:

True   True   True   True   True   True   True   True

Содержимое коллекции bа2:

True   True   False  False  False  False  True   False

Результат логической операции ba XOR bа2:

False  False  True   True   True   True   False  True


Специальные коллекции

В среде .NET Framework предусмотрен ряд специальных коллекций, оптимизированных для работы с данными конкретного типа или для их обработки особым образом. Классы этих необобщенных коллекций определены в пространстве имен System.Collections.Specialized и перечислены ниже.

Класс специальной коллекции – Описание

CollectionsUtil – Содержит фабричные методы для создания коллекций

HybridDictionary – Предназначен для коллекций, в которых для хранения небольшого количества пар “ключ-значение” используется класс ListDictionary. При превышении коллекцией определенного размера автоматически используется класс Hashtable для хранения ее элементов

ListDictionary – Предназначен для коллекций, в которых для хранения пар “ключ-значение" используется связный список. Такие коллекции рекомендуются только для хранения небольшого количества элементов

NameValueCollection – Предназначен для отсортированных коллекций, в которых хранятся пары “ключ-значение”, причем и ключ, и значение относятся к типу string

OrderedDictionary – Предназначен для коллекций, в которых хранятся индексируемые пары “ключ-значение”

StringCollection – Предназначен для коллекций, оптимизированных для хранения символьных строк

StringDictionary – Предназначен для хеш-таблиц, в которых хранятся пары “ключ-значение”, причем и ключ, и значение относятся к типу string

Кроме того, в пространстве имен System.Collections определены три базовых абстрактных класса: CollectionBase, ReadOnlyCollectionBase и DictionaryBase. Эти классы могут наследоваться и служить в качестве отправной точки для разработки собственных специальных коллекций.


Обобщенные коллекции

Благодаря внедрению обобщений прикладной интерфейс Collections API значительно расширился, в результате чего количество классов коллекций и интерфейсов удвоилось. Обобщенные коллекции объявляются в пространстве имен System.Collections.Generic. Как правило, классы обобщенных коллекций являются не более чем обобщенными эквивалентами рассматривавшихся ранее классов необобщенных коллекций, хотя это соответствие не является взаимно однозначным. Например, в классе обобщенной коллекции LinkedList реализуется двунаправленный список, тогда как в необобщенном эквиваленте его не существует. В некоторых случаях одни и те же функции существуют параллельно в классах обобщенных и необобщенных коллекций, хотя и под разными именами. Так, обобщенный вариант класса ArrayList называется List, а обобщенный вариант класса HashTableDictionary. Кроме того, конкретное содержимое различных интерфейсов и классов реорганизуется с минимальными изменениями для переноса некоторых функций из одного интерфейса в другой. Но в целом, имея ясное представление о необобщенных коллекциях, можно без особого труда научиться применять и обобщенные коллекции.

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

Обобщенные коллекции определяются в ряде интерфейсов и классов, реализующих эти интерфейсы. Все они описываются далее по порядку.


    Ваша оценка произведения:

Популярные книги за неделю