Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c#_theoretical_2.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
750.08 Кб
Скачать

Узагальнені колекції

Узагальнені колекції визначено у просторі імен System.Collections.Generic. Як правило, класи узагальнених колекцій є не більше ніж узагальненими еквівалентами класів неузагальнених колекцій, окремі з яких ми розглянули вище. Однак ця відповідність не є взаємно однозначною. Наприклад, у класі узагальненої колекції LinkedList реалізується двонаправлений список, тоді як у неузагальненому еквіваленті його не існує. У деяких випадках одні і ті ж функції існують паралельно у класах узагальнених і неузагальнених колекцій, хоча й під різними іменами. Так, узагальнений варіант класу ArrayList називається List, а узагальнений варіант класу Hashtable − Dictionary. Нижче наведено відповідність між деякими основними узагальненнями та їх неузагальненими прототипами.

Неузагальнений

прототип

Узагальнення

Призначення

IComparer

IComparer<T>

Є узагальненим варіантом розглянутого раніше інтерфейсу IСomparer. Головна відмінність між ними полягає в тому, що інтерфейс IСomparer<T> забезпечує типову безпеку. У ньому узагальнений варіант методу Compare() оголошується в такий спосіб: int Compare(Т х, Т у).

IEnumerable, IEnumerator

IEnumerable<T>, IEnumerator<T>

Є узагальненими еквівалентами розглянутих раніше неузагальнених інтерфейсів IEnumerable та IЕnumerator. У них оголошуються аналогічні методи та властивості. Зрозуміло, що узагальнені інтерфейси оперують даними тільки того типу, який вказується в аргументі типу. Але між інтерфейсами IЕnumerator та IЕnumerator<T> є одна важлива відмінність: інтерфейс IЕnumerator<T> успадковує від інтерфейсу IDisposable, тоді як інтерфейс IЕnumerator не є похідним від нього.

ICollection

ICollection<T>

Визначає ряд властивостей, які є спільними для всіх узагальнених колекцій. Узагальнення містить більше методів у порівнянні зі своїм неузагальненим прототипом.

IList

IList<T>

Визначає таку поведінку узагальненої колекції, яка дозволяє здійснювати доступ до її елементів за індексом, починаючи від нуля.

IDictionary

IDictionary<TKey, TValue>

Визначає таку поведінку узагальненої колекції, яка дозволяє перетворити унікальні ключі у відповідні значення. Іншими словами − в даному інтерфейсі визначається колекція, у якій зберігаються пари «ключ-значення».

Stack

Stack<T>

Забезпечує такі ж функціональні можливості, як і неузагальнений клас Stack.

Queue

Queue<T>

Забезпечує такі ж функціональні можливості, як і неузагальнений клас Queue.

ArrayList

List<T>

Забезпечує такі ж функціональні можливості, як і неузагальнений клас ArrayList.

Hashtable

Dictionary<TKey, TValue>

Забезпечує такі ж функціональні можливості, як і неузагальнений клас Hashtable.

DictionaryEntry

KeyValuePair<TKey, TValue>

Застосовується в класах узагальнених колекцій, у яких зберігаються пари «ключ-значення».

Маючи чітке уявлення про неузагальнені колекції, можна без особливих труднощів навчитися застосовувати й узагальнені колекції. Як правило, узагальнені колекції діють за тим самим принципом, що й неузагальнені, за винятком того, що узагальнені колекції типізовані. Це означає, що в узагальненій колекції можна зберігати тільки ті елементи, які сумісні по типу з її аргументом типу. Так, якщо потрібна колекція для зберігання різнотипних даних, то слід використовувати класи неузагальнених колекцій. А у всіх інших випадках, коли в колекції повинні зберігатися об’єкти тільки одного типу, рекомендується використовувати класи узагальнених колекцій.

Як приклад, що використовує узагальнений словник, наведемо клас для роботи із розрідженими дійснозначними матрицями. Розрідженою називається матриця, яка містить велику кількість нульових елементів. Такі матриці часто виникають у задачах лінійної алгебри, математичної фізики та оптимізації. Зберігання цих матриць традиційним способом вимагає суттєвих затрат пам’яті. Особливо це неефективно при великих розмірах матриці та великій кількості нульових елементів. У цьому випадку матрицю можна зберігати у вигляді колекції, яка містить тільки ненульові елементи. Для представлення розрідженої матриці можна використовувати наступну систему класів:

  • структуру для представлення індексів та значення одного елемента дійснозначної матриці (element);

  • клас для представлення матриці у вигляді узагальненого динамічного масиву, який містить інформацію про ненульові елементи (SparseMatrix).

// структура, яка описує індекси та значення елемента матриці

public struct element

{

public readonly int i;

public readonly int j;

public double value;

public element(int i0, int j0, double value0)

{

i = i0;

j = j0;

value = value0;

}

}

// клас розрідженої матриці із дійсними елементами

// у відповідному узагальненому динамічному масиві зберігаються тільки ненульові елементи

// розрідженої матриці

class SparseMatrix : List<element>

{

// поля, що описують розмірність розрідженої матриці

public readonly int rowCount;

public readonly int colCount;

// конструктор з параметрами

public SparseMatrix(int rowCount0, int colCount0)

{

rowCount = rowCount0;

colCount = colCount0;

}

// індексатор доступу до елементів метриці за їх індексами

public double this[int row, int column]

{

get

{

// визначаємо, чи міститься елемент у колекції

int index = -1;

for (int k = 0; k < this.Count; k++ )

if (this[k].i == row & this[k].j == column)

{

index = k;

break;

}

if (index >= 0)

// у випадку, коли індекси елемента присутні у колекції, то повертаємо відповідне

// значення елемента розрідженої матриці

return this[index].value;

// інакше це нульовий елемент, тому повертаємо 0

return 0;

}

set

{

// визначаємо, чи міститься елемент у колекції

int index = this.IndexOf(new element(row, column, value));

// якщо обнуляємо ненульовий елемент

if (index >= 0 & value == 0)

{

this.RemoveAt(index);

this.TrimExcess();

}

// якщо змінюємо значення ненульового елементу на інше ненульове значення

if (index >= 0 & value != 0)

this[index] = new element(row, column, value);

// якщо нульовий елемент змінюємо на ненульове значення

if (index < 0 & value != 0)

{

this.Add(new element(row, column, value));

this.TrimExcess();

}

}

}

// метод виводу розрідженої матриці на екран

public void Display()

{

Console.WriteLine("[{0}", nonzeroCount);

for (int i = 0; i < rowCount; i++)

{

for (int j = 0; j < colCount; j++)

Console.Write(" {0}", this[i, j]);

Console.WriteLine();

}

Console.WriteLine("]");

}

// властивість, яка повертає кількість ненульових елементів розрідженої матриці

public int nonzeroCount

{

get { return this.Count; }

}

// перевантаження операції додавання двох розріджених дійснозначних матриць

public static SparseMatrix operator +(SparseMatrix M1, SparseMatrix M2)

{

if (M1.rowCount == M2.rowCount & M1.colCount == M2.colCount)

{

SparseMatrix S = new SparseMatrix(M1.rowCount, M1.colCount);

for (int i = 0; i < S.rowCount; i++)

for (int j = 0; j < S.colCount; j++)

S[i, j] = M1[i, j] + M2[i, j];

return S;

}

else

throw new ArgumentException("Цi матрицi не можна додати: вони мають рiзнi розмірностi!");

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]