Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка - Основи Програмування C_.doc
Скачиваний:
46
Добавлен:
18.12.2018
Размер:
1.44 Mб
Скачать

2. Використання списку ArrayList та узагальненого списку List

Узагальнений список типу ArrayList (цей клас знаходиться в просторі імен System.Collections) можна використовувати для організації даних довільних типів. Всі дані, що містяться в цій колекції, мають тип System.Object, від якого успадковані всі типи даних. Розглянемо приклад роботи з цим класом

using System;

using System.Collections;

namespace LabDemo

{

class Program

{

static void Main(string[] args)

{

// ініціалізуємо перелік

ArrayList al = new ArrayList();

// поки що колекція порожня, але до неї можна додати

// довільні об'єкти

al.Add("Slon"); // додали рядок

// додамо елементи масиву

al.AddRange(new int[] { 1, 2, 3, 4 });

// додамо цілий масив як один елемент

al.Add(new int[] { 5, 6, 7, 8 });

// дані можна вставляти після довільної позиції,

// наприклад, після третьої (адже першою є позиція 0!)

al.Insert(2, "Giraf");

// отримати дані можна з допомогою циклу foreach

foreach (object o in al)

{ Console.WriteLine(o); }

Console.WriteLine("=============");

// елементи можна видаляти за значенням

al.Remove(3); // видалили елемент із значенням 3

// елементи можна видаляти також за індексом

al.RemoveAt(0); // видалили початковий елемент

//елементи можна перебрати з допомогою звичайного циклу for

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

{

// до елементів можна звертатись за номером індексу

Console.WriteLine(al[i]);

}

// елементи завжди можна перетворити на звичайний масив

object[] ob = al.ToArray(); // маємо масив обєктів

}

}

}

В результаті виконання цієї програми на екрані побачимо:

Slon 1

Зауваження:

  1. Поточна кількість елементів в колекціях типу ArrayList та List<T> визначається властивістю Count. Кількість елементів, для збереження яких виділена пам’ять, визначається властивістю Capacity.

  2. До колекцій типу ArrayList та List<T> можна додавати елементи по одному в кінець (метод Add) та всередину (метод Insert).

  3. До колекцій типу ArrayList та List<T> можна додавати групу елементів разом (масивом) в кінець колекції (метод AddRange) та всередину (метод InsertRange).

  4. З колекцій типу ArrayList та List<T> можна видаляти елементи за індексом (метод RemoveAt) або за значенням (метод Remove). Потрібно зазначити, що видалення елементу, який відноситься до reference-типу, відбувається за порівнянням посилань, тобто так, як працює оператор ==.

  5. Колекції типу ArrayList та List<T> можна перетворити на масив за допомогою виклику методу ToArray (у випадку нетипізованої колекції метод поверне масив object [], інакше повертається масив того типу об’єктів, з типу якого складена колекція).

Але для отримання значення з переліку ArrayList потрібно виконати явне перетворення типів вигляду:

int i = (int) al[2];

або

int i = Convert.ToInt32(al[3]);

Такі операції суттєво уповільнюють виконання програми, і тому на зміну колекції ArrayList прийшов клас List<T>. Він знаходиться у просторі імен System.Collections.Generic і реалізує так звані типізовані колекції, тобто колекції, в яких тип елементів задається на етапі компіляції. Всі дані, що включаються до цієї колекції, перевіряються на сумісність ще на етапі компіляції. Це зменшує кількість помилок при розробці програми та пришвидшує виконання самої програми. Розглянемо приклад роботи із колекцією List<T>.

using System;

using System.Collections.Generic;

namespace LabDemo

{

class Program

{

static void Main(string[] args)

{

// працюємо з типізованим списком

List<int> l = new List<int>();

l.Add(10);

l.Add('c');

l.Add((int)4L);

foreach (int i in l)

{

Console.WriteLine(i);

}

}

}

}

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

using System;

using System.Collections;

namespace UseColletionSpeed

{

// оцінка швидкодії сортування колекції ArrayList

class Program

{

static void Main(string[] args)

{

// декларуємо колекцію для збереження даних

ArrayList a = new ArrayList();

Random r = new Random(); // генератор випадкових чисел

DateTime t1 = DateTime.Now; // початковий час

// наповнюємо ArrayList 4 мільйонами елементів

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

{

a.Add(r.Next());

}

a.Sort(); // виконуємо сортування елементів колекції

DateTime t2 = DateTime.Now; // кінцевий час

// інтервал часу між початком та завершенням роботи

TimeSpan s = t2.Subtract(t1);

// виводимо результат

Console.WriteLine(s.Seconds * 1000 + s.Milliseconds);

}

}

}

Тест показав 7593 мілісекунди. Змінемо цю програму для використання типізованої колекції наступним чином:

using System;

using System.Collections.Generic;

namespace UseColletionSpeed

{

// оцінка швидкодії сортування колекції List< >

class Program

{

static void Main(string[] args)

{

// декларуємо колекцію для збереження даних

List<int> a = new List<int>();

Random r = new Random(); // генератор випадкових чисел

DateTime t1 = DateTime.Now; // початковий час

// наповнюємо List< > 4 мільйонами елементів

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

{

a.Add(r.Next());

}

a.Sort(); // виконуємо сортування елементів колекції

DateTime t2 = DateTime.Now; // кінцевий час

// інтервал часу між початком та завершенням роботи

TimeSpan s = t2.Subtract(t1);

// виводимо результат

Console.WriteLine(s.Seconds * 1000 + s.Milliseconds);

}

}

}

Тепер інтервал часу зменшиться до 1091 мілісекунди на тому ж самому обладнанні. Оцінимо, як зміниться інтервал часу роботи при переході від типізованої колекції до звичайного масиву у наступному прикладі:

using System;

namespace UseColletionSpeed

{

// оцінка швидкодії сортування масиву

class Program

{

static void Main(string[] args)

{

// декларуємо масив для збереження

int[] a = new int[4000000];

Random r = new Random(); // генератор випадкових чисел

DateTime t1 = DateTime.Now; // початковий час

// наповнюємо масив 4 мільйонами елементів

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

{

a[i] = r.Next();

}

Array.Sort(a); // виконуємо сортування елементів масиву

DateTime t2 = DateTime.Now; // кінцевий час

// інтервал часу між початком та завершенням роботи

TimeSpan s = t2.Subtract(t1);

// виводимо результат

Console.WriteLine(s.Seconds * 1000 + s.Milliseconds);

}

}

}

Тут швидкість програми майже не змінилась (890 мілісекунд).

Таким чином, можна зробити висновок, що при передачі даних між фрагментами програми для збільшення швидкодії корисно перетворювати колекції на масиви з допомогою методу ToArray. Зазначимо, що насправді колекції містять саме масиви (це можна перевірити за допомогою .NET рефлектору).